home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / atarigen.c < prev    next >
C/C++ Source or Header  |  2000-05-13  |  79KB  |  3,258 lines

  1. /***************************************************************************
  2.  
  3.   atarigen.c
  4.  
  5.   General functions for mid-to-late 80's Atari raster games.
  6.  
  7. ***************************************************************************/
  8.  
  9.  
  10. #include "driver.h"
  11. #include "atarigen.h"
  12. #include "cpu/m6502/m6502.h"
  13.  
  14.  
  15. /*--------------------------------------------------------------------------
  16.  
  17.     Atari generic interrupt model (required)
  18.  
  19.         atarigen_scanline_int_state - state of the scanline interrupt line
  20.         atarigen_sound_int_state - state of the sound interrupt line
  21.         atarigen_video_int_state - state of the video interrupt line
  22.  
  23.         atarigen_int_callback - called when the interrupt state changes
  24.  
  25.         atarigen_interrupt_reset - resets & initializes the interrupt state
  26.         atarigen_update_interrupts - forces the interrupts to be reevaluted
  27.  
  28.         atarigen_scanline_int_set - scanline interrupt initialization
  29.         atarigen_scanline_int_gen - scanline interrupt generator
  30.         atarigen_scanline_int_ack_w - scanline interrupt acknowledgement
  31.  
  32.         atarigen_sound_int_gen - sound interrupt generator
  33.         atarigen_sound_int_ack_w - sound interrupt acknowledgement
  34.  
  35.         atarigen_video_int_gen - video interrupt generator
  36.         atarigen_video_int_ack_w - video interrupt acknowledgement
  37.  
  38. --------------------------------------------------------------------------*/
  39.  
  40. /* globals */
  41. int atarigen_scanline_int_state;
  42. int atarigen_sound_int_state;
  43. int atarigen_video_int_state;
  44.  
  45. /* statics */
  46. static atarigen_int_callback update_int_callback;
  47. static void *scanline_interrupt_timer;
  48.  
  49. /* prototypes */
  50. static void scanline_interrupt_callback(int param);
  51.  
  52.  
  53. /*
  54.  *    Interrupt initialization
  55.  *
  56.  *    Resets the various interrupt states.
  57.  *
  58.  */
  59.  
  60. void atarigen_interrupt_reset(atarigen_int_callback update_int)
  61. {
  62.     /* set the callback */
  63.     update_int_callback = update_int;
  64.  
  65.     /* reset the interrupt states */
  66.     atarigen_video_int_state = atarigen_sound_int_state = atarigen_scanline_int_state = 0;
  67.     scanline_interrupt_timer = NULL;
  68. }
  69.  
  70.  
  71. /*
  72.  *    Update interrupts
  73.  *
  74.  *    Forces the interrupt callback to be called with the current VBLANK and sound interrupt states.
  75.  *
  76.  */
  77.  
  78. void atarigen_update_interrupts(void)
  79. {
  80.     (*update_int_callback)();
  81. }
  82.  
  83.  
  84.  
  85. /*
  86.  *    Scanline interrupt initialization
  87.  *
  88.  *    Sets the scanline when the next scanline interrupt should be generated.
  89.  *
  90.  */
  91.  
  92. void atarigen_scanline_int_set(int scanline)
  93. {
  94.     if (scanline_interrupt_timer)
  95.         timer_remove(scanline_interrupt_timer);
  96.     scanline_interrupt_timer = timer_set(cpu_getscanlinetime(scanline), 0, scanline_interrupt_callback);
  97. }
  98.  
  99.  
  100. /*
  101.  *    Scanline interrupt generator
  102.  *
  103.  *    Standard interrupt routine which sets the scanline interrupt state.
  104.  *
  105.  */
  106.  
  107. int atarigen_scanline_int_gen(void)
  108. {
  109.     atarigen_scanline_int_state = 1;
  110.     (*update_int_callback)();
  111.     return 0;
  112. }
  113.  
  114.  
  115. /*
  116.  *    Scanline interrupt acknowledge write handler
  117.  *
  118.  *    Resets the state of the scanline interrupt.
  119.  *
  120.  */
  121.  
  122. WRITE_HANDLER( atarigen_scanline_int_ack_w )
  123. {
  124.     atarigen_scanline_int_state = 0;
  125.     (*update_int_callback)();
  126. }
  127.  
  128.  
  129. /*
  130.  *    Sound interrupt generator
  131.  *
  132.  *    Standard interrupt routine which sets the sound interrupt state.
  133.  *
  134.  */
  135.  
  136. int atarigen_sound_int_gen(void)
  137. {
  138.     atarigen_sound_int_state = 1;
  139.     (*update_int_callback)();
  140.     return 0;
  141. }
  142.  
  143.  
  144. /*
  145.  *    Sound interrupt acknowledge write handler
  146.  *
  147.  *    Resets the state of the sound interrupt.
  148.  *
  149.  */
  150.  
  151. WRITE_HANDLER( atarigen_sound_int_ack_w )
  152. {
  153.     atarigen_sound_int_state = 0;
  154.     (*update_int_callback)();
  155. }
  156.  
  157.  
  158. /*
  159.  *    Video interrupt generator
  160.  *
  161.  *    Standard interrupt routine which sets the video interrupt state.
  162.  *
  163.  */
  164.  
  165. int atarigen_video_int_gen(void)
  166. {
  167.     atarigen_video_int_state = 1;
  168.     (*update_int_callback)();
  169.     return 0;
  170. }
  171.  
  172.  
  173. /*
  174.  *    Video interrupt acknowledge write handler
  175.  *
  176.  *    Resets the state of the video interrupt.
  177.  *
  178.  */
  179.  
  180. WRITE_HANDLER( atarigen_video_int_ack_w )
  181. {
  182.     atarigen_video_int_state = 0;
  183.     (*update_int_callback)();
  184. }
  185.  
  186.  
  187. /*
  188.  *    Scanline interrupt generator
  189.  *
  190.  *    Signals an interrupt.
  191.  *
  192.  */
  193.  
  194. static void scanline_interrupt_callback(int param)
  195. {
  196.     /* generate the interrupt */
  197.     atarigen_scanline_int_gen();
  198.  
  199.     /* set a new timer to go off at the same scan line next frame */
  200.     scanline_interrupt_timer = timer_set(TIME_IN_HZ(Machine->drv->frames_per_second), 0, scanline_interrupt_callback);
  201. }
  202.  
  203.  
  204.  
  205. /*--------------------------------------------------------------------------
  206.  
  207.     EEPROM I/O (optional)
  208.  
  209.         atarigen_eeprom_default - pointer to compressed default data
  210.         atarigen_eeprom - pointer to base of EEPROM memory
  211.         atarigen_eeprom_size - size of EEPROM memory
  212.  
  213.         atarigen_eeprom_reset - resets the EEPROM system
  214.  
  215.         atarigen_eeprom_enable_w - write handler to enable EEPROM access
  216.         atarigen_eeprom_w - write handler for EEPROM data (low byte)
  217.         atarigen_eeprom_r - read handler for EEPROM data (low byte)
  218.  
  219.         atarigen_nvram_handler - load/save EEPROM data
  220.  
  221. --------------------------------------------------------------------------*/
  222.  
  223. /* globals */
  224. const UINT16 *atarigen_eeprom_default;
  225. UINT8 *atarigen_eeprom;
  226. size_t atarigen_eeprom_size;
  227.  
  228. /* statics */
  229. static UINT8 unlocked;
  230.  
  231. /* prototypes */
  232. static void decompress_eeprom_word(const UINT16 *data);
  233. static void decompress_eeprom_byte(const UINT16 *data);
  234.  
  235.  
  236. /*
  237.  *    EEPROM reset
  238.  *
  239.  *    Makes sure that the unlocked state is cleared when we reset.
  240.  *
  241.  */
  242.  
  243. void atarigen_eeprom_reset(void)
  244. {
  245.     unlocked = 0;
  246. }
  247.  
  248.  
  249. /*
  250.  *    EEPROM enable write handler
  251.  *
  252.  *    Any write to this handler will allow one byte to be written to the
  253.  *    EEPROM data area the next time.
  254.  *
  255.  */
  256.  
  257. WRITE_HANDLER( atarigen_eeprom_enable_w )
  258. {
  259.     unlocked = 1;
  260. }
  261.  
  262.  
  263. /*
  264.  *    EEPROM write handler (low byte of word)
  265.  *
  266.  *    Writes a "word" to the EEPROM, which is almost always accessed via
  267.  *    the low byte of the word only. If the EEPROM hasn't been unlocked,
  268.  *    the write attempt is ignored.
  269.  *
  270.  */
  271.  
  272. WRITE_HANDLER( atarigen_eeprom_w )
  273. {
  274.     if (!unlocked)
  275.         return;
  276.  
  277.     COMBINE_WORD_MEM(&atarigen_eeprom[offset], data);
  278.     unlocked = 0;
  279. }
  280.  
  281.  
  282. /*
  283.  *    EEPROM read handler (low byte of word)
  284.  *
  285.  *    Reads a "word" from the EEPROM, which is almost always accessed via
  286.  *    the low byte of the word only.
  287.  *
  288.  */
  289.  
  290. READ_HANDLER( atarigen_eeprom_r )
  291. {
  292.     return READ_WORD(&atarigen_eeprom[offset]) | 0xff00;
  293. }
  294.  
  295. READ_HANDLER( atarigen_eeprom_upper_r )
  296. {
  297.     return READ_WORD(&atarigen_eeprom[offset]) | 0x00ff;
  298. }
  299.  
  300.  
  301. /*
  302.  *    Standard high score load
  303.  *
  304.  *    Loads the EEPROM data as a "high score".
  305.  *
  306.  */
  307.  
  308. void atarigen_nvram_handler(void *file,int read_or_write)
  309. {
  310.     if (read_or_write)
  311.         osd_fwrite(file, atarigen_eeprom, atarigen_eeprom_size);
  312.     else
  313.     {
  314.         if (file)
  315.             osd_fread(file, atarigen_eeprom, atarigen_eeprom_size);
  316.         else
  317.         {
  318.             /* all 0xff's work for most games */
  319.             memset(atarigen_eeprom, 0xff, atarigen_eeprom_size);
  320.  
  321.             /* anything else must be decompressed */
  322.             if (atarigen_eeprom_default)
  323.             {
  324.                 if (atarigen_eeprom_default[0] == 0)
  325.                     decompress_eeprom_byte(atarigen_eeprom_default + 1);
  326.                 else
  327.                     decompress_eeprom_word(atarigen_eeprom_default + 1);
  328.             }
  329.         }
  330.     }
  331. }
  332.  
  333.  
  334.  
  335. /*
  336.  *    Decompress word-based EEPROM data
  337.  *
  338.  *    Used for decompressing EEPROM data that has every other byte invalid.
  339.  *
  340.  */
  341.  
  342. void decompress_eeprom_word(const UINT16 *data)
  343. {
  344.     UINT16 *dest = (UINT16 *)atarigen_eeprom;
  345.     UINT16 value;
  346.  
  347.     while ((value = *data++) != 0)
  348.     {
  349.         int count = (value >> 8);
  350.         value = (value << 8) | (value & 0xff);
  351.  
  352.         while (count--)
  353.         {
  354.             WRITE_WORD(dest, value);
  355.             dest++;
  356.         }
  357.     }
  358. }
  359.  
  360.  
  361. /*
  362.  *    Decompress byte-based EEPROM data
  363.  *
  364.  *    Used for decompressing EEPROM data that is byte-packed.
  365.  *
  366.  */
  367.  
  368. void decompress_eeprom_byte(const UINT16 *data)
  369. {
  370.     UINT8 *dest = (UINT8 *)atarigen_eeprom;
  371.     UINT16 value;
  372.  
  373.     while ((value = *data++) != 0)
  374.     {
  375.         int count = (value >> 8);
  376.         value = (value << 8) | (value & 0xff);
  377.  
  378.         while (count--)
  379.             *dest++ = value;
  380.     }
  381. }
  382.  
  383.  
  384.  
  385. /*--------------------------------------------------------------------------
  386.  
  387.     Slapstic I/O (optional)
  388.  
  389.         atarigen_slapstic - pointer to base of slapstic memory
  390.  
  391.         atarigen_slapstic_init - select and initialize the slapstic handlers
  392.         atarigen_slapstic_reset - resets the slapstic state
  393.  
  394.         atarigen_slapstic_w - write handler for slapstic data
  395.         atarigen_slapstic_r - read handler for slapstic data
  396.  
  397.         slapstic_init - low-level init routine
  398.         slapstic_reset - low-level reset routine
  399.         slapstic_bank - low-level routine to return the current bank
  400.         slapstic_tweak - low-level tweak routine
  401.  
  402. --------------------------------------------------------------------------*/
  403.  
  404. /* globals */
  405. static UINT8 atarigen_slapstic_num;
  406. static UINT8 *atarigen_slapstic;
  407.  
  408.  
  409. /*
  410.  *    Slapstic initialization
  411.  *
  412.  *    Installs memory handlers for the slapstic and sets the chip number.
  413.  *
  414.  */
  415.  
  416. void atarigen_slapstic_init(int cpunum, int base, int chipnum)
  417. {
  418.     atarigen_slapstic_num = chipnum;
  419.     atarigen_slapstic = NULL;
  420.     if (chipnum)
  421.     {
  422.         slapstic_init(chipnum);
  423.         atarigen_slapstic = install_mem_read_handler(cpunum, base, base + 0x7fff, atarigen_slapstic_r);
  424.         atarigen_slapstic = install_mem_write_handler(cpunum, base, base + 0x7fff, atarigen_slapstic_w);
  425.     }
  426. }
  427.  
  428.  
  429. /*
  430.  *    Slapstic initialization
  431.  *
  432.  *    Makes the selected slapstic number active and resets its state.
  433.  *
  434.  */
  435.  
  436. void atarigen_slapstic_reset(void)
  437. {
  438.     if (atarigen_slapstic_num)
  439.         slapstic_reset();
  440. }
  441.  
  442.  
  443. /*
  444.  *    Slapstic write handler
  445.  *
  446.  *    Assuming that the slapstic sits in ROM memory space, we just simply
  447.  *    tweak the slapstic at this address and do nothing more.
  448.  *
  449.  */
  450.  
  451. WRITE_HANDLER( atarigen_slapstic_w )
  452. {
  453.     slapstic_tweak(offset / 2);
  454. }
  455.  
  456.  
  457. /*
  458.  *    Slapstic read handler
  459.  *
  460.  *    Tweaks the slapstic at the appropriate address and then reads a
  461.  *    word from the underlying memory.
  462.  *
  463.  */
  464.  
  465. READ_HANDLER( atarigen_slapstic_r )
  466. {
  467.     int bank = slapstic_tweak(offset / 2) * 0x2000;
  468.     return READ_WORD(&atarigen_slapstic[bank + (offset & 0x1fff)]);
  469. }
  470.  
  471.  
  472.  
  473.  
  474. /***********************************************************************************************/
  475. /***********************************************************************************************/
  476. /***********************************************************************************************/
  477. /***********************************************************************************************/
  478. /***********************************************************************************************/
  479.  
  480.  
  481.  
  482. /*--------------------------------------------------------------------------
  483.  
  484.     Sound I/O
  485.  
  486.         atarigen_sound_io_reset - reset the sound I/O system
  487.  
  488.         atarigen_6502_irq_gen - standard 6502 IRQ interrupt generator
  489.         atarigen_6502_irq_ack_r - standard 6502 IRQ interrupt acknowledgement
  490.         atarigen_6502_irq_ack_w - standard 6502 IRQ interrupt acknowledgement
  491.  
  492.         atarigen_ym2151_irq_gen - YM2151 sound IRQ generator
  493.  
  494.         atarigen_sound_w - Main CPU -> sound CPU data write (low byte)
  495.         atarigen_sound_r - Sound CPU -> main CPU data read (low byte)
  496.         atarigen_sound_upper_w - Main CPU -> sound CPU data write (high byte)
  497.         atarigen_sound_upper_r - Sound CPU -> main CPU data read (high byte)
  498.  
  499.         atarigen_sound_reset_w - 6502 CPU reset
  500.         atarigen_6502_sound_w - Sound CPU -> main CPU data write
  501.         atarigen_6502_sound_r - Main CPU -> sound CPU data read
  502.  
  503. --------------------------------------------------------------------------*/
  504.  
  505. /* constants */
  506. #define SOUND_INTERLEAVE_RATE        TIME_IN_USEC(50)
  507. #define SOUND_INTERLEAVE_REPEAT        20
  508.  
  509. /* globals */
  510. int atarigen_cpu_to_sound_ready;
  511. int atarigen_sound_to_cpu_ready;
  512.  
  513. /* statics */
  514. static UINT8 sound_cpu_num;
  515. static UINT8 atarigen_cpu_to_sound;
  516. static UINT8 atarigen_sound_to_cpu;
  517. static UINT8 timed_int;
  518. static UINT8 ym2151_int;
  519.  
  520. /* prototypes */
  521. static void update_6502_irq(void);
  522. static void sound_comm_timer(int reps_left);
  523. static void delayed_sound_reset(int param);
  524. static void delayed_sound_w(int param);
  525. static void delayed_6502_sound_w(int param);
  526.  
  527.  
  528. /*
  529.  *    Sound I/O reset
  530.  *
  531.  *    Resets the state of the sound I/O.
  532.  *
  533.  */
  534.  
  535. void atarigen_sound_io_reset(int cpu_num)
  536. {
  537.     /* remember which CPU is the sound CPU */
  538.     sound_cpu_num = cpu_num;
  539.  
  540.     /* reset the internal interrupts states */
  541.     timed_int = ym2151_int = 0;
  542.  
  543.     /* reset the sound I/O states */
  544.     atarigen_cpu_to_sound = atarigen_sound_to_cpu = 0;
  545.     atarigen_cpu_to_sound_ready = atarigen_sound_to_cpu_ready = 0;
  546. }
  547.  
  548.  
  549. /*
  550.  *    6502 IRQ generator
  551.  *
  552.  *    Generates an IRQ signal to the 6502 sound processor.
  553.  *
  554.  */
  555.  
  556. int atarigen_6502_irq_gen(void)
  557. {
  558.     timed_int = 1;
  559.     update_6502_irq();
  560.     return 0;
  561. }
  562.  
  563.  
  564. /*
  565.  *    6502 IRQ acknowledgement
  566.  *
  567.  *    Resets the IRQ signal to the 6502 sound processor. Both reads and writes can be used.
  568.  *
  569.  */
  570.  
  571. READ_HANDLER( atarigen_6502_irq_ack_r )
  572. {
  573.     timed_int = 0;
  574.     update_6502_irq();
  575.     return 0;
  576. }
  577.  
  578. WRITE_HANDLER( atarigen_6502_irq_ack_w )
  579. {
  580.     timed_int = 0;
  581.     update_6502_irq();
  582. }
  583.  
  584.  
  585. /*
  586.  *    YM2151 IRQ generation
  587.  *
  588.  *    Sets the state of the YM2151's IRQ line.
  589.  *
  590.  */
  591.  
  592. void atarigen_ym2151_irq_gen(int irq)
  593. {
  594.     ym2151_int = irq;
  595.     update_6502_irq();
  596. }
  597.  
  598.  
  599. /*
  600.  *    Sound CPU write handler
  601.  *
  602.  *    Write handler which resets the sound CPU in response.
  603.  *
  604.  */
  605.  
  606. WRITE_HANDLER( atarigen_sound_reset_w )
  607. {
  608.     timer_set(TIME_NOW, 0, delayed_sound_reset);
  609. }
  610.  
  611.  
  612. /*
  613.  *    Sound CPU reset handler
  614.  *
  615.  *    Resets the state of the sound CPU manually.
  616.  *
  617.  */
  618.  
  619. void atarigen_sound_reset(void)
  620. {
  621.     timer_set(TIME_NOW, 1, delayed_sound_reset);
  622. }
  623.  
  624.  
  625. /*
  626.  *    Main -> sound CPU data write handlers
  627.  *
  628.  *    Handles communication from the main CPU to the sound CPU. Two versions are provided,
  629.  *    one with the data byte in the low 8 bits, and one with the data byte in the upper 8
  630.  *    bits.
  631.  *
  632.  */
  633.  
  634. WRITE_HANDLER( atarigen_sound_w )
  635. {
  636.     if (!(data & 0x00ff0000))
  637.         timer_set(TIME_NOW, data & 0xff, delayed_sound_w);
  638. }
  639.  
  640. WRITE_HANDLER( atarigen_sound_upper_w )
  641. {
  642.     if (!(data & 0xff000000))
  643.         timer_set(TIME_NOW, (data >> 8) & 0xff, delayed_sound_w);
  644. }
  645.  
  646.  
  647. /*
  648.  *    Sound -> main CPU data read handlers
  649.  *
  650.  *    Handles reading data communicated from the sound CPU to the main CPU. Two versions
  651.  *    are provided, one with the data byte in the low 8 bits, and one with the data byte
  652.  *    in the upper 8 bits.
  653.  *
  654.  */
  655.  
  656. READ_HANDLER( atarigen_sound_r )
  657. {
  658.     atarigen_sound_to_cpu_ready = 0;
  659.     atarigen_sound_int_ack_w(0, 0);
  660.     return atarigen_sound_to_cpu | 0xff00;
  661. }
  662.  
  663. READ_HANDLER( atarigen_sound_upper_r )
  664. {
  665.     atarigen_sound_to_cpu_ready = 0;
  666.     atarigen_sound_int_ack_w(0, 0);
  667.     return (atarigen_sound_to_cpu << 8) | 0x00ff;
  668. }
  669.  
  670.  
  671. /*
  672.  *    Sound -> main CPU data write handler
  673.  *
  674.  *    Handles communication from the sound CPU to the main CPU.
  675.  *
  676.  */
  677.  
  678. WRITE_HANDLER( atarigen_6502_sound_w )
  679. {
  680.     timer_set(TIME_NOW, data, delayed_6502_sound_w);
  681. }
  682.  
  683.  
  684. /*
  685.  *    Main -> sound CPU data read handler
  686.  *
  687.  *    Handles reading data communicated from the main CPU to the sound CPU.
  688.  *
  689.  */
  690.  
  691. READ_HANDLER( atarigen_6502_sound_r )
  692. {
  693.     atarigen_cpu_to_sound_ready = 0;
  694.     cpu_set_nmi_line(sound_cpu_num, CLEAR_LINE);
  695.     return atarigen_cpu_to_sound;
  696. }
  697.  
  698.  
  699. /*
  700.  *    6502 IRQ state updater
  701.  *
  702.  *    Called whenever the IRQ state changes. An interrupt is generated if
  703.  *    either atarigen_6502_irq_gen() was called, or if the YM2151 generated
  704.  *    an interrupt via the atarigen_ym2151_irq_gen() callback.
  705.  *
  706.  */
  707.  
  708. void update_6502_irq(void)
  709. {
  710.     if (timed_int || ym2151_int)
  711.         cpu_set_irq_line(sound_cpu_num, M6502_INT_IRQ, ASSERT_LINE);
  712.     else
  713.         cpu_set_irq_line(sound_cpu_num, M6502_INT_IRQ, CLEAR_LINE);
  714. }
  715.  
  716.  
  717. /*
  718.  *    Sound communications timer
  719.  *
  720.  *    Set whenever a command is written from the main CPU to the sound CPU, in order to
  721.  *    temporarily bump up the interleave rate. This helps ensure that communications
  722.  *    between the two CPUs works properly.
  723.  *
  724.  */
  725.  
  726. static void sound_comm_timer(int reps_left)
  727. {
  728.     if (--reps_left)
  729.         timer_set(SOUND_INTERLEAVE_RATE, reps_left, sound_comm_timer);
  730. }
  731.  
  732.  
  733. /*
  734.  *    Sound CPU reset timer
  735.  *
  736.  *    Synchronizes the sound reset command between the two CPUs.
  737.  *
  738.  */
  739.  
  740. static void delayed_sound_reset(int param)
  741. {
  742.     /* unhalt and reset the sound CPU */
  743.     if (param == 0)
  744.     {
  745.         cpu_set_halt_line(sound_cpu_num, CLEAR_LINE);
  746.         cpu_set_reset_line(sound_cpu_num, PULSE_LINE);
  747.     }
  748.  
  749.     /* reset the sound write state */
  750.     atarigen_sound_to_cpu_ready = 0;
  751.     atarigen_sound_int_ack_w(0, 0);
  752. }
  753.  
  754.  
  755. /*
  756.  *    Main -> sound data write timer
  757.  *
  758.  *    Synchronizes a data write from the main CPU to the sound CPU.
  759.  *
  760.  */
  761.  
  762. static void delayed_sound_w(int param)
  763. {
  764.     /* warn if we missed something */
  765.     if (atarigen_cpu_to_sound_ready)
  766.         logerror("Missed command from 68010\n");
  767.  
  768.     /* set up the states and signal an NMI to the sound CPU */
  769.     atarigen_cpu_to_sound = param;
  770.     atarigen_cpu_to_sound_ready = 1;
  771.     cpu_set_nmi_line(sound_cpu_num, ASSERT_LINE);
  772.  
  773.     /* allocate a high frequency timer until a response is generated */
  774.     /* the main CPU is *very* sensistive to the timing of the response */
  775.     timer_set(SOUND_INTERLEAVE_RATE, SOUND_INTERLEAVE_REPEAT, sound_comm_timer);
  776. }
  777.  
  778.  
  779. /*
  780.  *    Sound -> main data write timer
  781.  *
  782.  *    Synchronizes a data write from the sound CPU to the main CPU.
  783.  *
  784.  */
  785.  
  786. static void delayed_6502_sound_w(int param)
  787. {
  788.     /* warn if we missed something */
  789.     if (atarigen_sound_to_cpu_ready)
  790.         logerror("Missed result from 6502\n");
  791.  
  792.     /* set up the states and signal the sound interrupt to the main CPU */
  793.     atarigen_sound_to_cpu = param;
  794.     atarigen_sound_to_cpu_ready = 1;
  795.     atarigen_sound_int_gen();
  796. }
  797.  
  798.  
  799.  
  800. /*--------------------------------------------------------------------------
  801.  
  802.     Misc sound helpers
  803.  
  804.         atarigen_init_6502_speedup - installs 6502 speedup cheat handler
  805.         atarigen_set_ym2151_vol - set the volume of the 2151 chip
  806.         atarigen_set_ym2413_vol - set the volume of the 2151 chip
  807.         atarigen_set_pokey_vol - set the volume of the POKEY chip(s)
  808.         atarigen_set_tms5220_vol - set the volume of the 5220 chip
  809.         atarigen_set_oki6295_vol - set the volume of the OKI6295
  810.  
  811. --------------------------------------------------------------------------*/
  812.  
  813. /* statics */
  814. static UINT8 *speed_a, *speed_b;
  815. static UINT32 speed_pc;
  816.  
  817. /* prototypes */
  818. static READ_HANDLER( m6502_speedup_r );
  819.  
  820.  
  821. /*
  822.  *    6502 CPU speedup cheat installer
  823.  *
  824.  *    Installs a special read handler to catch the main spin loop in the
  825.  *    6502 sound code. The addresses accessed seem to be the same across
  826.  *    a large number of games, though the PC shifts.
  827.  *
  828.  */
  829.  
  830. void atarigen_init_6502_speedup(int cpunum, int compare_pc1, int compare_pc2)
  831. {
  832.     UINT8 *memory = memory_region(REGION_CPU1+cpunum);
  833.     int address_low, address_high;
  834.  
  835.     /* determine the pointer to the first speed check location */
  836.     address_low = memory[compare_pc1 + 1] | (memory[compare_pc1 + 2] << 8);
  837.     address_high = memory[compare_pc1 + 4] | (memory[compare_pc1 + 5] << 8);
  838.     if (address_low != address_high - 1)
  839.         logerror("Error: address %04X does not point to a speedup location!", compare_pc1);
  840.     speed_a = &memory[address_low];
  841.  
  842.     /* determine the pointer to the second speed check location */
  843.     address_low = memory[compare_pc2 + 1] | (memory[compare_pc2 + 2] << 8);
  844.     address_high = memory[compare_pc2 + 4] | (memory[compare_pc2 + 5] << 8);
  845.     if (address_low != address_high - 1)
  846.         logerror("Error: address %04X does not point to a speedup location!", compare_pc2);
  847.     speed_b = &memory[address_low];
  848.  
  849.     /* install a handler on the second address */
  850.     speed_pc = compare_pc2;
  851.     install_mem_read_handler(cpunum, address_low, address_low, m6502_speedup_r);
  852. }
  853.  
  854.  
  855. /*
  856.  *    Set the YM2151 volume
  857.  *
  858.  *    What it says.
  859.  *
  860.  */
  861.  
  862. void atarigen_set_ym2151_vol(int volume)
  863. {
  864.     int ch;
  865.  
  866.     for (ch = 0; ch < MIXER_MAX_CHANNELS; ch++)
  867.     {
  868.         const char *name = mixer_get_name(ch);
  869.         if (name && strstr(name, "2151"))
  870.             mixer_set_volume(ch, volume);
  871.     }
  872. }
  873.  
  874.  
  875. /*
  876.  *    Set the YM2413 volume
  877.  *
  878.  *    What it says.
  879.  *
  880.  */
  881.  
  882. void atarigen_set_ym2413_vol(int volume)
  883. {
  884.     int ch;
  885.  
  886.     for (ch = 0; ch < MIXER_MAX_CHANNELS; ch++)
  887.     {
  888.         const char *name = mixer_get_name(ch);
  889.         if (name && strstr(name, "3812"))/*"2413")) -- need this change until 2413 stands alone */
  890.             mixer_set_volume(ch, volume);
  891.     }
  892. }
  893.  
  894.  
  895. /*
  896.  *    Set the POKEY volume
  897.  *
  898.  *    What it says.
  899.  *
  900.  */
  901.  
  902. void atarigen_set_pokey_vol(int volume)
  903. {
  904.     int ch;
  905.  
  906.     for (ch = 0; ch < MIXER_MAX_CHANNELS; ch++)
  907.     {
  908.         const char *name = mixer_get_name(ch);
  909.         if (name && strstr(name, "POKEY"))
  910.             mixer_set_volume(ch, volume);
  911.     }
  912. }
  913.  
  914.  
  915. /*
  916.  *    Set the TMS5220 volume
  917.  *
  918.  *    What it says.
  919.  *
  920.  */
  921.  
  922. void atarigen_set_tms5220_vol(int volume)
  923. {
  924.     int ch;
  925.  
  926.     for (ch = 0; ch < MIXER_MAX_CHANNELS; ch++)
  927.     {
  928.         const char *name = mixer_get_name(ch);
  929.         if (name && strstr(name, "5220"))
  930.             mixer_set_volume(ch, volume);
  931.     }
  932. }
  933.  
  934.  
  935. /*
  936.  *    Set the OKI6295 volume
  937.  *
  938.  *    What it says.
  939.  *
  940.  */
  941.  
  942. void atarigen_set_oki6295_vol(int volume)
  943. {
  944.     int ch;
  945.  
  946.     for (ch = 0; ch < MIXER_MAX_CHANNELS; ch++)
  947.     {
  948.         const char *name = mixer_get_name(ch);
  949.         if (name && strstr(name, "6295"))
  950.             mixer_set_volume(ch, volume);
  951.     }
  952. }
  953.  
  954.  
  955. /*
  956.  *    Generic 6502 CPU speedup handler
  957.  *
  958.  *    Special shading renderer that runs any pixels under pen 1 through a lookup table.
  959.  *
  960.  */
  961.  
  962. static READ_HANDLER( m6502_speedup_r )
  963. {
  964.     int result = speed_b[0];
  965.  
  966.     if (cpu_getpreviouspc() == speed_pc && speed_a[0] == speed_a[1] && result == speed_b[1])
  967.         cpu_spinuntil_int();
  968.  
  969.     return result;
  970. }
  971.  
  972.  
  973.  
  974.  
  975. /***********************************************************************************************/
  976. /***********************************************************************************************/
  977. /***********************************************************************************************/
  978. /***********************************************************************************************/
  979. /***********************************************************************************************/
  980.  
  981.  
  982.  
  983. /* general video globals */
  984. UINT8 *atarigen_playfieldram;
  985. UINT8 *atarigen_playfield2ram;
  986. UINT8 *atarigen_playfieldram_color;
  987. UINT8 *atarigen_playfield2ram_color;
  988. UINT8 *atarigen_spriteram;
  989. UINT8 *atarigen_alpharam;
  990. UINT8 *atarigen_vscroll;
  991. UINT8 *atarigen_hscroll;
  992.  
  993. size_t atarigen_playfieldram_size;
  994. size_t atarigen_playfield2ram_size;
  995. size_t atarigen_spriteram_size;
  996. size_t atarigen_alpharam_size;
  997.  
  998.  
  999.  
  1000. /*--------------------------------------------------------------------------
  1001.  
  1002.     Video scanline timing
  1003.  
  1004.         atarigen_scanline_timer_reset - call to reset the system
  1005.  
  1006. --------------------------------------------------------------------------*/
  1007.  
  1008. /* statics */
  1009. static atarigen_scanline_callback scanline_callback;
  1010. static int scanlines_per_callback;
  1011. static double scanline_callback_period;
  1012. static int last_scanline;
  1013.  
  1014. /* prototypes */
  1015. static void vblank_timer(int param);
  1016. static void scanline_timer(int scanline);
  1017.  
  1018. /*
  1019.  *    Scanline timer callback
  1020.  *
  1021.  *    Called once every n scanlines to generate the periodic callback to the main system.
  1022.  *
  1023.  */
  1024.  
  1025. void atarigen_scanline_timer_reset(atarigen_scanline_callback update_graphics, int frequency)
  1026. {
  1027.     /* set the scanline callback */
  1028.     scanline_callback = update_graphics;
  1029.     scanline_callback_period = (double)frequency * cpu_getscanlineperiod();
  1030.     scanlines_per_callback = frequency;
  1031.  
  1032.     /* compute the last scanline */
  1033.     last_scanline = (int)(TIME_IN_HZ(Machine->drv->frames_per_second) / cpu_getscanlineperiod());
  1034.  
  1035.     /* set a timer to go off on the next VBLANK */
  1036.     timer_set(cpu_getscanlinetime(Machine->drv->screen_height), 0, vblank_timer);
  1037. }
  1038.  
  1039.  
  1040. /*
  1041.  *    VBLANK timer callback
  1042.  *
  1043.  *    Called once every VBLANK to prime the scanline timers.
  1044.  *
  1045.  */
  1046.  
  1047. static void vblank_timer(int param)
  1048. {
  1049.     /* set a timer to go off at scanline 0 */
  1050.     timer_set(TIME_IN_USEC(Machine->drv->vblank_duration), 0, scanline_timer);
  1051.  
  1052.     /* set a timer to go off on the next VBLANK */
  1053.     timer_set(cpu_getscanlinetime(Machine->drv->screen_height), 1, vblank_timer);
  1054. }
  1055.  
  1056.  
  1057. /*
  1058.  *    Scanline timer callback
  1059.  *
  1060.  *    Called once every n scanlines to generate the periodic callback to the main system.
  1061.  *
  1062.  */
  1063.  
  1064. static void scanline_timer(int scanline)
  1065. {
  1066.     /* if this is scanline 0, we reset the MO and playfield system */
  1067.     if (scanline == 0)
  1068.     {
  1069.         atarigen_mo_reset();
  1070.         atarigen_pf_reset();
  1071.         atarigen_pf2_reset();
  1072.     }
  1073.  
  1074.     /* callback */
  1075.     if (scanline_callback)
  1076.     {
  1077.         (*scanline_callback)(scanline);
  1078.  
  1079.         /* generate another? */
  1080.         scanline += scanlines_per_callback;
  1081.         if (scanline < last_scanline && scanlines_per_callback)
  1082.             timer_set(scanline_callback_period, scanline, scanline_timer);
  1083.     }
  1084. }
  1085.  
  1086.  
  1087.  
  1088. /*--------------------------------------------------------------------------
  1089.  
  1090.     Video Controller I/O: used in Shuuz, Thunderjaws, Relief Pitcher, Off the Wall
  1091.  
  1092.         atarigen_video_control_data - pointer to base of control memory
  1093.         atarigen_video_control_latch1 - latch #1 value (-1 means disabled)
  1094.         atarigen_video_control_latch2 - latch #2 value (-1 means disabled)
  1095.  
  1096.         atarigen_video_control_reset - initializes the video controller
  1097.  
  1098.         atarigen_video_control_w - write handler for the video controller
  1099.         atarigen_video_control_r - read handler for the video controller
  1100.  
  1101. --------------------------------------------------------------------------*/
  1102.  
  1103. /* globals */
  1104. UINT8 *atarigen_video_control_data;
  1105. struct atarigen_video_control_state_desc atarigen_video_control_state;
  1106.  
  1107. /* statics */
  1108. static int actual_video_control_latch1;
  1109. static int actual_video_control_latch2;
  1110.  
  1111.  
  1112. /*
  1113.  *    Video controller initialization
  1114.  *
  1115.  *    Resets the state of the video controller.
  1116.  *
  1117.  */
  1118.  
  1119. void atarigen_video_control_reset(void)
  1120. {
  1121.     /* clear the RAM we use */
  1122.     memset(atarigen_video_control_data, 0, 0x40);
  1123.     memset(&atarigen_video_control_state, 0, sizeof(atarigen_video_control_state));
  1124.  
  1125.     /* reset the latches */
  1126.     atarigen_video_control_state.latch1 = atarigen_video_control_state.latch2 = -1;
  1127.     actual_video_control_latch1 = actual_video_control_latch2 = -1;
  1128. }
  1129.  
  1130.  
  1131. /*
  1132.  *    Video controller update
  1133.  *
  1134.  *    Copies the data from the specified location once/frame into the video controller registers
  1135.  *
  1136.  */
  1137.  
  1138. void atarigen_video_control_update(const UINT8 *data)
  1139. {
  1140.     int i;
  1141.  
  1142.     /* echo all the commands to the video controller */
  1143.     for (i = 0; i < 0x38; i += 2)
  1144.         if (READ_WORD(&data[i]))
  1145.             atarigen_video_control_w(i, READ_WORD(&data[i]));
  1146.  
  1147.     /* use this for debugging the video controller values */
  1148. #if 0
  1149.     if (keyboard_pressed(KEYCODE_8))
  1150.     {
  1151.         static FILE *out;
  1152.         if (!out) out = fopen("scroll.log", "w");
  1153.         if (out)
  1154.         {
  1155.             for (i = 0; i < 64; i++)
  1156.                 fprintf(out, "%04X ", READ_WORD(&data[2 * i]));
  1157.             fprintf(out, "\n");
  1158.         }
  1159.     }
  1160. #endif
  1161. }
  1162.  
  1163.  
  1164. /*
  1165.  *    Video controller write
  1166.  *
  1167.  *    Handles an I/O write to the video controller.
  1168.  *
  1169.  */
  1170.  
  1171. WRITE_HANDLER( atarigen_video_control_w )
  1172. {
  1173.     int oldword = READ_WORD(&atarigen_video_control_data[offset]);
  1174.     int newword = COMBINE_WORD(oldword, data);
  1175.     WRITE_WORD(&atarigen_video_control_data[offset], newword);
  1176.  
  1177.     /* switch off the offset */
  1178.     switch (offset)
  1179.     {
  1180.         /* set the scanline interrupt here */
  1181.         case 0x06:
  1182.             if (oldword != newword)
  1183.                 atarigen_scanline_int_set(newword & 0x1ff);
  1184.             break;
  1185.  
  1186.         /* latch enable */
  1187.         case 0x14:
  1188.  
  1189.             /* reset the latches when disabled */
  1190.             if (!(newword & 0x0080))
  1191.                 atarigen_video_control_state.latch1 = atarigen_video_control_state.latch2 = -1;
  1192.             else
  1193.                 atarigen_video_control_state.latch1 = actual_video_control_latch1,
  1194.                 atarigen_video_control_state.latch2 = actual_video_control_latch2;
  1195.  
  1196.             /* check for rowscroll enable */
  1197.             atarigen_video_control_state.rowscroll_enable = (newword & 0x2000) >> 13;
  1198.  
  1199.             /* check for palette banking */
  1200.             atarigen_video_control_state.palette_bank = ((newword & 0x0400) >> 10) ^ 1;
  1201.             break;
  1202.  
  1203.         /* indexed parameters */
  1204.         case 0x20: case 0x22: case 0x24: case 0x26:
  1205.         case 0x28: case 0x2a: case 0x2c: case 0x2e:
  1206.         case 0x30: case 0x32: case 0x34: case 0x36:
  1207.             switch (newword & 15)
  1208.             {
  1209.                 case 9:
  1210.                     atarigen_video_control_state.sprite_xscroll = (newword >> 7) & 0x1ff;
  1211.                     break;
  1212.  
  1213.                 case 10:
  1214.                     atarigen_video_control_state.pf2_xscroll = (newword >> 7) & 0x1ff;
  1215.                     break;
  1216.  
  1217.                 case 11:
  1218.                     atarigen_video_control_state.pf1_xscroll = (newword >> 7) & 0x1ff;
  1219.                     break;
  1220.  
  1221.                 case 13:
  1222.                     atarigen_video_control_state.sprite_yscroll = (newword >> 7) & 0x1ff;
  1223.                     break;
  1224.  
  1225.                 case 14:
  1226.                     atarigen_video_control_state.pf2_yscroll = (newword >> 7) & 0x1ff;
  1227.                     break;
  1228.  
  1229.                 case 15:
  1230.                     atarigen_video_control_state.pf1_yscroll = (newword >> 7) & 0x1ff;
  1231.                     break;
  1232.             }
  1233.             break;
  1234.  
  1235.         /* latch 1 value */
  1236.         case 0x38:
  1237.             actual_video_control_latch1 = newword;
  1238.             actual_video_control_latch2 = -1;
  1239.             if (READ_WORD(&atarigen_video_control_data[0x14]) & 0x80)
  1240.                 atarigen_video_control_state.latch1 = actual_video_control_latch1;
  1241.             break;
  1242.  
  1243.         /* latch 2 value */
  1244.         case 0x3a:
  1245.             actual_video_control_latch1 = -1;
  1246.             actual_video_control_latch2 = newword;
  1247.             if (READ_WORD(&atarigen_video_control_data[0x14]) & 0x80)
  1248.                 atarigen_video_control_state.latch2 = actual_video_control_latch2;
  1249.             break;
  1250.  
  1251.         /* scanline IRQ ack here */
  1252.         case 0x3c:
  1253.             atarigen_scanline_int_ack_w(0, 0);
  1254.             break;
  1255.  
  1256.         /* log anything else */
  1257.         case 0x00:
  1258.         default:
  1259.             if (oldword != newword)
  1260.                 logerror("video_control_w(%02X, %04X) ** [prev=%04X]\n", offset, newword, oldword);
  1261.             break;
  1262.     }
  1263. }
  1264.  
  1265.  
  1266. /*
  1267.  *    Video controller read
  1268.  *
  1269.  *    Handles an I/O read from the video controller.
  1270.  *
  1271.  */
  1272.  
  1273. READ_HANDLER( atarigen_video_control_r )
  1274. {
  1275.     logerror("video_control_r(%02X)\n", offset);
  1276.  
  1277.     /* a read from offset 0 returns the current scanline */
  1278.     /* also sets bit 0x4000 if we're in VBLANK */
  1279.     if (offset == 0)
  1280.     {
  1281.         int result = cpu_getscanline();
  1282.  
  1283.         if (result > 255)
  1284.             result = 255;
  1285.         if (result > Machine->drv->visible_area.max_y)
  1286.             result |= 0x4000;
  1287.  
  1288.         return result;
  1289.     }
  1290.     else
  1291.         return READ_WORD(&atarigen_video_control_data[offset]);
  1292. }
  1293.  
  1294.  
  1295.  
  1296. /*--------------------------------------------------------------------------
  1297.  
  1298.     Motion object rendering
  1299.  
  1300.         atarigen_mo_desc - description of the M.O. layout
  1301.  
  1302.         atarigen_mo_callback - called back for each M.O. during processing
  1303.  
  1304.         atarigen_mo_init - initializes and configures the M.O. list walker
  1305.         atarigen_mo_free - frees all memory allocated by atarigen_mo_init
  1306.         atarigen_mo_reset - reset for a new frame (use only if not using interrupt system)
  1307.         atarigen_mo_update - updates the M.O. list for the given scanline
  1308.         atarigen_mo_process - processes the current list
  1309.  
  1310. --------------------------------------------------------------------------*/
  1311.  
  1312. /* statics */
  1313. static struct atarigen_mo_desc modesc;
  1314.  
  1315. static UINT16 *molist;
  1316. static UINT16 *molist_end;
  1317. static UINT16 *molist_last;
  1318. static UINT16 *molist_upper_bound;
  1319.  
  1320.  
  1321. /*
  1322.  *    Motion object render initialization
  1323.  *
  1324.  *    Allocates memory for the motion object display cache.
  1325.  *
  1326.  */
  1327.  
  1328. int atarigen_mo_init(const struct atarigen_mo_desc *source_desc)
  1329. {
  1330.     modesc = *source_desc;
  1331.     if (modesc.entrywords == 0) modesc.entrywords = 4;
  1332.     modesc.entrywords++;
  1333.  
  1334.     /* make sure everything is free */
  1335.     atarigen_mo_free();
  1336.  
  1337.     /* allocate memory for the cached list */
  1338.     molist = malloc(modesc.maxcount * 2 * modesc.entrywords * (Machine->drv->screen_height / 8));
  1339.     if (!molist)
  1340.         return 1;
  1341.     molist_upper_bound = molist + (modesc.maxcount * modesc.entrywords * (Machine->drv->screen_height / 8));
  1342.  
  1343.     /* initialize the end/last pointers */
  1344.     atarigen_mo_reset();
  1345.  
  1346.     return 0;
  1347. }
  1348.  
  1349.  
  1350. /*
  1351.  *    Motion object render free
  1352.  *
  1353.  *    Frees all data allocated for the motion objects.
  1354.  *
  1355.  */
  1356.  
  1357. void atarigen_mo_free(void)
  1358. {
  1359.     if (molist)
  1360.         free(molist);
  1361.     molist = NULL;
  1362. }
  1363.  
  1364.  
  1365. /*
  1366.  *    Motion object render reset
  1367.  *
  1368.  *    Resets the motion object system for a new frame. Note that this is automatically called
  1369.  *    if you're using the scanline timing system.
  1370.  *
  1371.  */
  1372.  
  1373. void atarigen_mo_reset(void)
  1374. {
  1375.     molist_end = molist;
  1376.     molist_last = NULL;
  1377. }
  1378.  
  1379.  
  1380. /*
  1381.  *    Motion object updater
  1382.  *
  1383.  *    Parses the current motion object list, caching all entries.
  1384.  *
  1385.  */
  1386.  
  1387. void atarigen_mo_update(const UINT8 *base, int link, int scanline)
  1388. {
  1389.     int entryskip = modesc.entryskip, wordskip = modesc.wordskip, wordcount = modesc.entrywords - 1;
  1390.     UINT8 spritevisit[ATARIGEN_MAX_MAXCOUNT];
  1391.     UINT16 *data, *data_start, *prev_data;
  1392.     int match = 0;
  1393.  
  1394.     /* set up local pointers */
  1395.     data_start = data = molist_end;
  1396.     prev_data = molist_last;
  1397.  
  1398.     /* if the last list entries were on the same scanline, overwrite them */
  1399.     if (prev_data)
  1400.     {
  1401.         if (*prev_data == scanline)
  1402.             data_start = data = prev_data;
  1403.         else
  1404.             match = 1;
  1405.     }
  1406.  
  1407.     /* visit all the sprites and copy their data into the display list */
  1408.     memset(spritevisit, 0, modesc.linkmask + 1);
  1409.     while (!spritevisit[link])
  1410.     {
  1411.         const UINT8 *modata = &base[link * entryskip];
  1412.         UINT16 tempdata[16];
  1413.         int temp, i;
  1414.  
  1415.         /* bounds checking */
  1416.         if (data >= molist_upper_bound)
  1417.         {
  1418.             logerror("Motion object list exceeded maximum\n");
  1419.             break;
  1420.         }
  1421.  
  1422.         /* start with the scanline */
  1423.         *data++ = scanline;
  1424.  
  1425.         /* add the data words */
  1426.         for (i = temp = 0; i < wordcount; i++, temp += wordskip)
  1427.             tempdata[i] = *data++ = READ_WORD(&modata[temp]);
  1428.  
  1429.         /* is this one to ignore? (note that ignore is predecremented by 4) */
  1430.         if (tempdata[modesc.ignoreword] == 0xffff)
  1431.             data -= wordcount + 1;
  1432.  
  1433.         /* update our match status */
  1434.         else if (match)
  1435.         {
  1436.             prev_data++;
  1437.             for (i = 0; i < wordcount; i++)
  1438.                 if (*prev_data++ != tempdata[i])
  1439.                 {
  1440.                     match = 0;
  1441.                     break;
  1442.                 }
  1443.         }
  1444.  
  1445.         /* link to the next object */
  1446.         spritevisit[link] = 1;
  1447.         if (modesc.linkword >= 0)
  1448.             link = (tempdata[modesc.linkword] >> modesc.linkshift) & modesc.linkmask;
  1449.         else
  1450.             link = (link + 1) & modesc.linkmask;
  1451.     }
  1452.  
  1453.     /* if we didn't match the last set of entries, update the counters */
  1454.     if (!match)
  1455.     {
  1456.         molist_end = data;
  1457.         molist_last = data_start;
  1458.     }
  1459. }
  1460.  
  1461.  
  1462. /*
  1463.  *    Motion object updater using SLIPs
  1464.  *
  1465.  *    Updates motion objects using a SLIP read from a table, assuming a 512-pixel high playfield.
  1466.  *
  1467.  */
  1468.  
  1469. void atarigen_mo_update_slip_512(const UINT8 *base, int scroll, int scanline, const UINT8 *slips)
  1470. {
  1471.     /* catch a fractional character off the top of the screen */
  1472.     if (scanline == 0 && (scroll & 7) != 0)
  1473.     {
  1474.         int pfscanline = scroll & 0x1f8;
  1475.         int link = (READ_WORD(&slips[2 * (pfscanline / 8)]) >> modesc.linkshift) & modesc.linkmask;
  1476.         atarigen_mo_update(base, link, 0);
  1477.     }
  1478.  
  1479.     /* if we're within screen bounds, grab the next batch of MO's and process */
  1480.     if (scanline < Machine->drv->screen_height)
  1481.     {
  1482.         int pfscanline = (scanline + scroll + 7) & 0x1f8;
  1483.         int link = (READ_WORD(&slips[2 * (pfscanline / 8)]) >> modesc.linkshift) & modesc.linkmask;
  1484.         atarigen_mo_update(base, link, (pfscanline - scroll) & 0x1ff);
  1485.     }
  1486. }
  1487.  
  1488.  
  1489. /*
  1490.  *    Motion object processor
  1491.  *
  1492.  *    Processes the cached motion object entries.
  1493.  *
  1494.  */
  1495.  
  1496. void atarigen_mo_process(atarigen_mo_callback callback, void *param)
  1497. {
  1498.     UINT16 *base = molist;
  1499.     int last_start_scan = -1;
  1500.     struct rectangle clip;
  1501.  
  1502.     /* create a clipping rectangle so that only partial sections are updated at a time */
  1503.     clip.min_x = 0;
  1504.     clip.max_x = Machine->drv->screen_width - 1;
  1505.  
  1506.     /* loop over the list until the end */
  1507.     while (base < molist_end)
  1508.     {
  1509.         UINT16 *data, *first, *last;
  1510.         int start_scan = base[0], step;
  1511.  
  1512.         last_start_scan = start_scan;
  1513.         clip.min_y = start_scan;
  1514.  
  1515.         /* look for an entry whose scanline start is different from ours; that's our bottom */
  1516.         for (data = base; data < molist_end; data += modesc.entrywords)
  1517.             if (*data != start_scan)
  1518.             {
  1519.                 clip.max_y = *data;
  1520.                 break;
  1521.             }
  1522.  
  1523.         /* if we didn't find any additional regions, go until the bottom of the screen */
  1524.         if (data == molist_end)
  1525.             clip.max_y = Machine->drv->screen_height - 1;
  1526.  
  1527.         /* set the start and end points */
  1528.         if (modesc.reverse)
  1529.         {
  1530.             first = data - modesc.entrywords;
  1531.             last = base - modesc.entrywords;
  1532.             step = -modesc.entrywords;
  1533.         }
  1534.         else
  1535.         {
  1536.             first = base;
  1537.             last = data;
  1538.             step = modesc.entrywords;
  1539.         }
  1540.  
  1541.         /* update the base */
  1542.         base = data;
  1543.  
  1544.         /* render the mos */
  1545.         for (data = first; data != last; data += step)
  1546.             (*callback)(&data[1], &clip, param);
  1547.     }
  1548. }
  1549.  
  1550.  
  1551.  
  1552. /*--------------------------------------------------------------------------
  1553.  
  1554.     RLE Motion object rendering/decoding
  1555.  
  1556.         atarigen_rle_init - prescans the RLE objects
  1557.         atarigen_rle_free - frees all memory allocated by atarigen_rle_init
  1558.         atarigen_rle_render - render an RLE-compressed motion object
  1559.  
  1560. --------------------------------------------------------------------------*/
  1561.  
  1562. /* globals */
  1563. int atarigen_rle_count;
  1564. struct atarigen_rle_descriptor *atarigen_rle_info;
  1565.  
  1566. /* statics */
  1567. static UINT8 rle_region;
  1568. static UINT8 rle_bpp[8];
  1569. static UINT16 *rle_table[8];
  1570. static UINT16 *rle_colortable;
  1571.  
  1572. /* prototypes */
  1573. static int build_rle_tables(void);
  1574. static void prescan_rle(int which);
  1575. static void draw_rle_zoom(struct osd_bitmap *bitmap, const struct atarigen_rle_descriptor *gfx,
  1576.         UINT32 color, int flipy, int sx, int sy, int scalex, int scaley,
  1577.         const struct rectangle *clip);
  1578. static void draw_rle_zoom_16(struct osd_bitmap *bitmap, const struct atarigen_rle_descriptor *gfx,
  1579.         UINT32 color, int flipy, int sx, int sy, int scalex, int scaley,
  1580.         const struct rectangle *clip);
  1581. static void draw_rle_zoom_hflip(struct osd_bitmap *bitmap, const struct atarigen_rle_descriptor *gfx,
  1582.         UINT32 color, int flipy, int sx, int sy, int scalex, int scaley,
  1583.         const struct rectangle *clip);
  1584. static void draw_rle_zoom_hflip_16(struct osd_bitmap *bitmap, const struct atarigen_rle_descriptor *gfx,
  1585.         UINT32 color, int flipy, int sx, int sy, int scalex, int scaley,
  1586.         const struct rectangle *clip);
  1587.  
  1588. /*
  1589.  *    RLE motion object initialization
  1590.  *
  1591.  *    Pre-parses the motion object list and potentially pre-decompresses the data.
  1592.  *
  1593.  */
  1594.  
  1595. int atarigen_rle_init(int region, int colorbase)
  1596. {
  1597.     const UINT16 *base = (const UINT16 *)memory_region(region);
  1598.     int lowest_address = memory_region_length(region);
  1599.     int i;
  1600.  
  1601.     rle_region = region;
  1602.     rle_colortable = &Machine->remapped_colortable[colorbase];
  1603.  
  1604.     /* build and allocate the tables */
  1605.     if (build_rle_tables())
  1606.         return 1;
  1607.  
  1608.     /* first determine the lowest address of all objects */
  1609.     for (i = 0; i < lowest_address; i += 4)
  1610.     {
  1611.         int offset = ((base[i + 2] & 0xff) << 16) | base[i + 3];
  1612.         if (offset > i && offset < lowest_address)
  1613.             lowest_address = offset;
  1614.     }
  1615.  
  1616.     /* that determines how many objects */
  1617.     atarigen_rle_count = lowest_address / 4;
  1618.     atarigen_rle_info = malloc(sizeof(struct atarigen_rle_descriptor) * atarigen_rle_count);
  1619.     if (!atarigen_rle_info)
  1620.     {
  1621.         atarigen_rle_free();
  1622.         return 1;
  1623.     }
  1624.     memset(atarigen_rle_info, 0, sizeof(struct atarigen_rle_descriptor) * atarigen_rle_count);
  1625.  
  1626.     /* now loop through and prescan the objects */
  1627.     for (i = 0; i < atarigen_rle_count; i++)
  1628.         prescan_rle(i);
  1629.  
  1630.     return 0;
  1631. }
  1632.  
  1633.  
  1634. /*
  1635.  *    RLE motion object free
  1636.  *
  1637.  *    Frees all memory allocated to track the motion objects.
  1638.  *
  1639.  */
  1640.  
  1641. void atarigen_rle_free(void)
  1642. {
  1643.     /* free the info data */
  1644.     if (atarigen_rle_info)
  1645.         free(atarigen_rle_info);
  1646.     atarigen_rle_info = NULL;
  1647.  
  1648.     /* free the tables */
  1649.     if (rle_table[0])
  1650.         free(rle_table[0]);
  1651.     memset(rle_table, 0, sizeof(rle_table));
  1652. }
  1653.  
  1654.  
  1655. /*
  1656.  *    RLE motion object render
  1657.  *
  1658.  *    Renders a compressed motion object.
  1659.  *
  1660.  */
  1661.  
  1662. void atarigen_rle_render(struct osd_bitmap *bitmap, struct atarigen_rle_descriptor *info, int color, int hflip, int vflip,
  1663.     int x, int y, int xscale, int yscale, const struct rectangle *clip)
  1664. {
  1665.     int scaled_xoffs = (xscale * info->xoffs) >> 12;
  1666.     int scaled_yoffs = (yscale * info->yoffs) >> 12;
  1667.  
  1668.     /* we're hflipped, account for it */
  1669.     if (hflip) scaled_xoffs = ((xscale * info->width) >> 12) - scaled_xoffs;
  1670.  
  1671.     /* adjust for the x and y offsets */
  1672.     x -= scaled_xoffs;
  1673.     y -= scaled_yoffs;
  1674.  
  1675.     /* bail on a NULL object */
  1676.     if (!info->data)
  1677.         return;
  1678.  
  1679.     /* 16-bit case */
  1680.     if (bitmap->depth == 16)
  1681.     {
  1682.         if (!hflip)
  1683.             draw_rle_zoom_16(bitmap, info, color, vflip, x, y, xscale << 4, yscale << 4, clip);
  1684.         else
  1685.             draw_rle_zoom_hflip_16(bitmap, info, color, vflip, x, y, xscale << 4, yscale << 4, clip);
  1686.     }
  1687.  
  1688.     /* 8-bit case */
  1689.     else
  1690.     {
  1691.         if (!hflip)
  1692.             draw_rle_zoom(bitmap, info, color, vflip, x, y, xscale << 4, yscale << 4, clip);
  1693.         else
  1694.             draw_rle_zoom_hflip(bitmap, info, color, vflip, x, y, xscale << 4, yscale << 4, clip);
  1695.     }
  1696. }
  1697.  
  1698.  
  1699. /*
  1700.  *    Builds internally-used tables
  1701.  *
  1702.  *    Special two-byte tables with the upper byte giving the count and the lower
  1703.  *    byte giving the pixel value.
  1704.  *
  1705.  */
  1706.  
  1707. static int build_rle_tables(void)
  1708. {
  1709.     UINT16 *base;
  1710.     int i;
  1711.  
  1712.     /* allocate all 5 tables */
  1713.     base = malloc(0x500 * sizeof(UINT16));
  1714.     if (!base)
  1715.         return 1;
  1716.  
  1717.     /* assign the tables */
  1718.     rle_table[0] = &base[0x000];
  1719.     rle_table[1] = &base[0x100];
  1720.     rle_table[2] = rle_table[3] = &base[0x200];
  1721.     rle_table[4] = rle_table[6] = &base[0x300];
  1722.     rle_table[5] = rle_table[7] = &base[0x400];
  1723.  
  1724.     /* set the bpps */
  1725.     rle_bpp[0] = 4;
  1726.     rle_bpp[1] = rle_bpp[2] = rle_bpp[3] = 5;
  1727.     rle_bpp[4] = rle_bpp[5] = rle_bpp[6] = rle_bpp[7] = 6;
  1728.  
  1729.     /* build the 4bpp table */
  1730.     for (i = 0; i < 256; i++)
  1731.         rle_table[0][i] = (((i & 0xf0) + 0x10) << 4) | (i & 0x0f);
  1732.  
  1733.     /* build the 5bpp table */
  1734.     for (i = 0; i < 256; i++)
  1735.         rle_table[2][i] = (((i & 0xe0) + 0x20) << 3) | (i & 0x1f);
  1736.  
  1737.     /* build the special 5bpp table */
  1738.     for (i = 0; i < 256; i++)
  1739.     {
  1740.         if ((i & 0x0f) == 0)
  1741.             rle_table[1][i] = (((i & 0xf0) + 0x10) << 4) | (i & 0x0f);
  1742.         else
  1743.             rle_table[1][i] = (((i & 0xe0) + 0x20) << 3) | (i & 0x1f);
  1744.     }
  1745.  
  1746.     /* build the 6bpp table */
  1747.     for (i = 0; i < 256; i++)
  1748.         rle_table[5][i] = (((i & 0xc0) + 0x40) << 2) | (i & 0x3f);
  1749.  
  1750.     /* build the special 6bpp table */
  1751.     for (i = 0; i < 256; i++)
  1752.     {
  1753.         if ((i & 0x0f) == 0)
  1754.             rle_table[4][i] = (((i & 0xf0) + 0x10) << 4) | (i & 0x0f);
  1755.         else
  1756.             rle_table[4][i] = (((i & 0xc0) + 0x40) << 2) | (i & 0x3f);
  1757.     }
  1758.  
  1759.     return 0;
  1760. }
  1761.  
  1762.  
  1763. /*
  1764.  *    Prescans an RLE-compressed object
  1765.  *
  1766.  *    Determines the pen usage, width, height, and other data for an RLE object.
  1767.  *
  1768.  */
  1769.  
  1770. static void prescan_rle(int which)
  1771. {
  1772.     UINT16 *base = (UINT16 *)&memory_region(rle_region)[which * 8];
  1773.     struct atarigen_rle_descriptor *rle_data = &atarigen_rle_info[which];
  1774.     UINT32 usage = 0, usage_hi = 0;
  1775.     int width = 0, height, flags, offset;
  1776.     const UINT16 *table;
  1777.  
  1778.     /* look up the offset */
  1779.     rle_data->xoffs = (INT16)base[0];
  1780.     rle_data->yoffs = (INT16)base[1];
  1781.  
  1782.     /* determine the depth and table */
  1783.     flags = base[2];
  1784.     rle_data->bpp = rle_bpp[(flags >> 8) & 7];
  1785.     table = rle_data->table = rle_table[(flags >> 8) & 7];
  1786.  
  1787.     /* determine the starting offset */
  1788.     offset = ((base[2] & 0xff) << 16) | base[3];
  1789.     rle_data->data = base = (UINT16 *)&memory_region(rle_region)[offset * 2];
  1790.  
  1791.     /* make sure it's valid */
  1792.     if (offset < which * 4 || offset > memory_region_length(rle_region))
  1793.     {
  1794.         memset(rle_data, 0, sizeof(*rle_data));
  1795.         return;
  1796.     }
  1797.  
  1798.     /* first pre-scan to determine the width and height */
  1799.     for (height = 0; height < 1024; height++)
  1800.     {
  1801.         int tempwidth = 0;
  1802.         int entry_count = *base++;
  1803.  
  1804.         /* if the high bit is set, assume we're inverted */
  1805.         if (entry_count & 0x8000)
  1806.         {
  1807.             entry_count ^= 0xffff;
  1808.  
  1809.             /* also change the ROM data so we don't have to do this again at runtime */
  1810.             base[-1] ^= 0xffff;
  1811.         }
  1812.  
  1813.         /* we're done when we hit 0 */
  1814.         if (entry_count == 0)
  1815.             break;
  1816.  
  1817.         /* track the width */
  1818.         while (entry_count--)
  1819.         {
  1820.             int word = *base++;
  1821.             int count, value;
  1822.  
  1823.             /* decode the low byte first */
  1824.             count = table[word & 0xff];
  1825.             value = count & 0xff;
  1826.             tempwidth += count >> 8;
  1827.             if (value < 32)
  1828.                 usage |= 1 << value;
  1829.             else
  1830.                 usage_hi |= 1 << (value - 32);
  1831.  
  1832.             /* decode the upper byte second */
  1833.             count = table[word >> 8];
  1834.             value = count & 0xff;
  1835.             tempwidth += count >> 8;
  1836.             if (value < 32)
  1837.                 usage |= 1 << value;
  1838.             else
  1839.                 usage_hi |= 1 << (value - 32);
  1840.         }
  1841.  
  1842.         /* only remember the max */
  1843.         if (tempwidth > width) width = tempwidth;
  1844.     }
  1845.  
  1846.     /* fill in the data */
  1847.     rle_data->width = width;
  1848.     rle_data->height = height;
  1849.     rle_data->pen_usage = usage;
  1850.     rle_data->pen_usage_hi = usage_hi;
  1851. }
  1852.  
  1853.  
  1854. /*
  1855.  *    Draw a compressed RLE object
  1856.  *
  1857.  *    What it says. RLE decoding is performed on the fly to an 8-bit bitmap.
  1858.  *
  1859.  */
  1860.  
  1861. void draw_rle_zoom(struct osd_bitmap *bitmap, const struct atarigen_rle_descriptor *gfx,
  1862.         UINT32 color, int flipy, int sx, int sy, int scalex, int scaley,
  1863.         const struct rectangle *clip)
  1864. {
  1865.     const UINT16 *palette = &rle_colortable[color];
  1866.     const UINT16 *row_start = gfx->data;
  1867.     const UINT16 *table = gfx->table;
  1868.     volatile int current_row = 0;
  1869.  
  1870.     int scaled_width = (scalex * gfx->width + 0x7fff) >> 16;
  1871.     int scaled_height = (scaley * gfx->height + 0x7fff) >> 16;
  1872.  
  1873.     int pixels_to_skip = 0, xclipped = 0;
  1874.     int dx, dy, ex, ey;
  1875.     int y, sourcey;
  1876.  
  1877.     /* make sure we didn't end up with 0 */
  1878.     if (scaled_width == 0) scaled_width = 1;
  1879.     if (scaled_height == 0) scaled_height = 1;
  1880.  
  1881.     /* compute the remaining parameters */
  1882.     dx = (gfx->width << 16) / scaled_width;
  1883.     dy = (gfx->height << 16) / scaled_height;
  1884.     ex = sx + scaled_width - 1;
  1885.     ey = sy + scaled_height - 1;
  1886.     sourcey = dy / 2;
  1887.  
  1888.     /* left edge clip */
  1889.     if (sx < clip->min_x)
  1890.         pixels_to_skip = clip->min_x - sx, xclipped = 1;
  1891.     if (sx > clip->max_x)
  1892.         return;
  1893.  
  1894.     /* right edge clip */
  1895.     if (ex > clip->max_x)
  1896.         ex = clip->max_x, xclipped = 1;
  1897.     else if (ex < clip->min_x)
  1898.         return;
  1899.  
  1900.     /* top edge clip */
  1901.     if (sy < clip->min_y)
  1902.     {
  1903.         sourcey += (clip->min_y - sy) * dy;
  1904.         sy = clip->min_y;
  1905.     }
  1906.     else if (sy > clip->max_y)
  1907.         return;
  1908.  
  1909.     /* bottom edge clip */
  1910.     if (ey > clip->max_y)
  1911.         ey = clip->max_y;
  1912.     else if (ey < clip->min_y)
  1913.         return;
  1914.  
  1915.     /* loop top to bottom */
  1916.     for (y = sy; y <= ey; y++, sourcey += dy)
  1917.     {
  1918.         UINT8 *dest = &bitmap->line[y][sx];
  1919.         int j, sourcex = dx / 2, rle_end = 0;
  1920.         const UINT16 *base;
  1921.         int entry_count;
  1922.  
  1923.         /* loop until we hit the row we're on */
  1924.         for ( ; current_row != (sourcey >> 16); current_row++)
  1925.             row_start += 1 + *row_start;
  1926.  
  1927.         /* grab our starting parameters from this row */
  1928.         base = row_start;
  1929.         entry_count = *base++;
  1930.  
  1931.         /* non-clipped case */
  1932.         if (!xclipped)
  1933.         {
  1934.             /* decode the pixels */
  1935.             for (j = 0; j < entry_count; j++)
  1936.             {
  1937.                 int word = *base++;
  1938.                 int count, value;
  1939.  
  1940.                 /* decode the low byte first */
  1941.                 count = table[word & 0xff];
  1942.                 value = count & 0xff;
  1943.                 rle_end += (count & 0xff00) << 8;
  1944.  
  1945.                 /* store copies of the value until we pass the end of this chunk */
  1946.                 if (value)
  1947.                 {
  1948.                     value = palette[value];
  1949.                     while (sourcex < rle_end)
  1950.                         *dest++ = value, sourcex += dx;
  1951.                 }
  1952.                 else
  1953.                 {
  1954.                     while (sourcex < rle_end)
  1955.                         dest++, sourcex += dx;
  1956.                 }
  1957.  
  1958.                 /* decode the upper byte second */
  1959.                 count = table[word >> 8];
  1960.                 value = count & 0xff;
  1961.                 rle_end += (count & 0xff00) << 8;
  1962.  
  1963.                 /* store copies of the value until we pass the end of this chunk */
  1964.                 if (value)
  1965.                 {
  1966.                     value = palette[value];
  1967.                     while (sourcex < rle_end)
  1968.                         *dest++ = value, sourcex += dx;
  1969.                 }
  1970.                 else
  1971.                 {
  1972.                     while (sourcex < rle_end)
  1973.                         dest++, sourcex += dx;
  1974.                 }
  1975.             }
  1976.         }
  1977.  
  1978.         /* clipped case */
  1979.         else
  1980.         {
  1981.             const UINT8 *end = &bitmap->line[y][ex];
  1982.             int to_be_skipped = pixels_to_skip;
  1983.  
  1984.             /* decode the pixels */
  1985.             for (j = 0; j < entry_count && dest <= end; j++)
  1986.             {
  1987.                 int word = *base++;
  1988.                 int count, value;
  1989.  
  1990.                 /* decode the low byte first */
  1991.                 count = table[word & 0xff];
  1992.                 value = count & 0xff;
  1993.                 rle_end += (count & 0xff00) << 8;
  1994.  
  1995.                 /* store copies of the value until we pass the end of this chunk */
  1996.                 if (to_be_skipped)
  1997.                 {
  1998.                     while (to_be_skipped && sourcex < rle_end)
  1999.                         dest++, sourcex += dx, to_be_skipped--;
  2000.                     if (to_be_skipped) goto next1;
  2001.                 }
  2002.                 if (value)
  2003.                 {
  2004.                     value = palette[value];
  2005.                     while (sourcex < rle_end && dest <= end)
  2006.                         *dest++ = value, sourcex += dx;
  2007.                 }
  2008.                 else
  2009.                 {
  2010.                     while (sourcex < rle_end)
  2011.                         dest++, sourcex += dx;
  2012.                 }
  2013.  
  2014.             next1:
  2015.                 /* decode the upper byte second */
  2016.                 count = table[word >> 8];
  2017.                 value = count & 0xff;
  2018.                 rle_end += (count & 0xff00) << 8;
  2019.  
  2020.                 /* store copies of the value until we pass the end of this chunk */
  2021.                 if (to_be_skipped)
  2022.                 {
  2023.                     while (to_be_skipped && sourcex < rle_end)
  2024.                         dest++, sourcex += dx, to_be_skipped--;
  2025.                     if (to_be_skipped) goto next2;
  2026.                 }
  2027.                 if (value)
  2028.                 {
  2029.                     value = palette[value];
  2030.                     while (sourcex < rle_end && dest <= end)
  2031.                         *dest++ = value, sourcex += dx;
  2032.                 }
  2033.                 else
  2034.                 {
  2035.                     while (sourcex < rle_end)
  2036.                         dest++, sourcex += dx;
  2037.                 }
  2038.             next2:
  2039.                 ;
  2040.             }
  2041.         }
  2042.     }
  2043. }
  2044.  
  2045.  
  2046. /*
  2047.  *    Draw a compressed RLE object
  2048.  *
  2049.  *    What it says. RLE decoding is performed on the fly to a 16-bit bitmap.
  2050.  *
  2051.  */
  2052.  
  2053. void draw_rle_zoom_16(struct osd_bitmap *bitmap, const struct atarigen_rle_descriptor *gfx,
  2054.         UINT32 color, int flipy, int sx, int sy, int scalex, int scaley,
  2055.         const struct rectangle *clip)
  2056. {
  2057.     const UINT16 *palette = &rle_colortable[color];
  2058.     const UINT16 *row_start = gfx->data;
  2059.     const UINT16 *table = gfx->table;
  2060.     volatile int current_row = 0;
  2061.  
  2062.     int scaled_width = (scalex * gfx->width + 0x7fff) >> 16;
  2063.     int scaled_height = (scaley * gfx->height + 0x7fff) >> 16;
  2064.  
  2065.     int pixels_to_skip = 0, xclipped = 0;
  2066.     int dx, dy, ex, ey;
  2067.     int y, sourcey;
  2068.  
  2069.     /* make sure we didn't end up with 0 */
  2070.     if (scaled_width == 0) scaled_width = 1;
  2071.     if (scaled_height == 0) scaled_height = 1;
  2072.  
  2073.     /* compute the remaining parameters */
  2074.     dx = (gfx->width << 16) / scaled_width;
  2075.     dy = (gfx->height << 16) / scaled_height;
  2076.     ex = sx + scaled_width - 1;
  2077.     ey = sy + scaled_height - 1;
  2078.     sourcey = dy / 2;
  2079.  
  2080.     /* left edge clip */
  2081.     if (sx < clip->min_x)
  2082.         pixels_to_skip = clip->min_x - sx, xclipped = 1;
  2083.     if (sx > clip->max_x)
  2084.         return;
  2085.  
  2086.     /* right edge clip */
  2087.     if (ex > clip->max_x)
  2088.         ex = clip->max_x, xclipped = 1;
  2089.     else if (ex < clip->min_x)
  2090.         return;
  2091.  
  2092.     /* top edge clip */
  2093.     if (sy < clip->min_y)
  2094.     {
  2095.         sourcey += (clip->min_y - sy) * dy;
  2096.         sy = clip->min_y;
  2097.     }
  2098.     else if (sy > clip->max_y)
  2099.         return;
  2100.  
  2101.     /* bottom edge clip */
  2102.     if (ey > clip->max_y)
  2103.         ey = clip->max_y;
  2104.     else if (ey < clip->min_y)
  2105.         return;
  2106.  
  2107.     /* loop top to bottom */
  2108.     for (y = sy; y <= ey; y++, sourcey += dy)
  2109.     {
  2110.         UINT16 *dest = (UINT16 *)&bitmap->line[y][sx * 2];
  2111.         int j, sourcex = dx / 2, rle_end = 0;
  2112.         const UINT16 *base;
  2113.         int entry_count;
  2114.  
  2115.         /* loop until we hit the row we're on */
  2116.         for ( ; current_row != (sourcey >> 16); current_row++)
  2117.             row_start += 1 + *row_start;
  2118.  
  2119.         /* grab our starting parameters from this row */
  2120.         base = row_start;
  2121.         entry_count = *base++;
  2122.  
  2123.         /* non-clipped case */
  2124.         if (!xclipped)
  2125.         {
  2126.             /* decode the pixels */
  2127.             for (j = 0; j < entry_count; j++)
  2128.             {
  2129.                 int word = *base++;
  2130.                 int count, value;
  2131.  
  2132.                 /* decode the low byte first */
  2133.                 count = table[word & 0xff];
  2134.                 value = count & 0xff;
  2135.                 rle_end += (count & 0xff00) << 8;
  2136.  
  2137.                 /* store copies of the value until we pass the end of this chunk */
  2138.                 if (value)
  2139.                 {
  2140.                     value = palette[value];
  2141.                     while (sourcex < rle_end)
  2142.                         *dest++ = value, sourcex += dx;
  2143.                 }
  2144.                 else
  2145.                 {
  2146.                     while (sourcex < rle_end)
  2147.                         dest++, sourcex += dx;
  2148.                 }
  2149.  
  2150.                 /* decode the upper byte second */
  2151.                 count = table[word >> 8];
  2152.                 value = count & 0xff;
  2153.                 rle_end += (count & 0xff00) << 8;
  2154.  
  2155.                 /* store copies of the value until we pass the end of this chunk */
  2156.                 if (value)
  2157.                 {
  2158.                     value = palette[value];
  2159.                     while (sourcex < rle_end)
  2160.                         *dest++ = value, sourcex += dx;
  2161.                 }
  2162.                 else
  2163.                 {
  2164.                     while (sourcex < rle_end)
  2165.                         dest++, sourcex += dx;
  2166.                 }
  2167.             }
  2168.         }
  2169.  
  2170.         /* clipped case */
  2171.         else
  2172.         {
  2173.             const UINT16 *end = (const UINT16 *)&bitmap->line[y][ex * 2];
  2174.             int to_be_skipped = pixels_to_skip;
  2175.  
  2176.             /* decode the pixels */
  2177.             for (j = 0; j < entry_count && dest <= end; j++)
  2178.             {
  2179.                 int word = *base++;
  2180.                 int count, value;
  2181.  
  2182.                 /* decode the low byte first */
  2183.                 count = table[word & 0xff];
  2184.                 value = count & 0xff;
  2185.                 rle_end += (count & 0xff00) << 8;
  2186.  
  2187.                 /* store copies of the value until we pass the end of this chunk */
  2188.                 if (to_be_skipped)
  2189.                 {
  2190.                     while (to_be_skipped && sourcex < rle_end)
  2191.                         dest++, sourcex += dx, to_be_skipped--;
  2192.                     if (to_be_skipped) goto next3;
  2193.                 }
  2194.                 if (value)
  2195.                 {
  2196.                     value = palette[value];
  2197.                     while (sourcex < rle_end && dest <= end)
  2198.                         *dest++ = value, sourcex += dx;
  2199.                 }
  2200.                 else
  2201.                 {
  2202.                     while (sourcex < rle_end)
  2203.                         dest++, sourcex += dx;
  2204.                 }
  2205.  
  2206.             next3:
  2207.                 /* decode the upper byte second */
  2208.                 count = table[word >> 8];
  2209.                 value = count & 0xff;
  2210.                 rle_end += (count & 0xff00) << 8;
  2211.  
  2212.                 /* store copies of the value until we pass the end of this chunk */
  2213.                 if (to_be_skipped)
  2214.                 {
  2215.                     while (to_be_skipped && sourcex < rle_end)
  2216.                         dest++, sourcex += dx, to_be_skipped--;
  2217.                     if (to_be_skipped) goto next4;
  2218.                 }
  2219.                 if (value)
  2220.                 {
  2221.                     value = palette[value];
  2222.                     while (sourcex < rle_end && dest <= end)
  2223.                         *dest++ = value, sourcex += dx;
  2224.                 }
  2225.                 else
  2226.                 {
  2227.                     while (sourcex < rle_end)
  2228.                         dest++, sourcex += dx;
  2229.                 }
  2230.             next4:
  2231.                 ;
  2232.             }
  2233.         }
  2234.     }
  2235. }
  2236.  
  2237.  
  2238. /*
  2239.  *    Draw a horizontally-flipped RLE-compressed object
  2240.  *
  2241.  *    What it says. RLE decoding is performed on the fly to an 8-bit bitmap.
  2242.  *
  2243.  */
  2244.  
  2245. void draw_rle_zoom_hflip(struct osd_bitmap *bitmap, const struct atarigen_rle_descriptor *gfx,
  2246.         UINT32 color, int flipy, int sx, int sy, int scalex, int scaley,
  2247.         const struct rectangle *clip)
  2248. {
  2249.     const UINT16 *palette = &rle_colortable[color];
  2250.     const UINT16 *row_start = gfx->data;
  2251.     const UINT16 *table = gfx->table;
  2252.     volatile int current_row = 0;
  2253.  
  2254.     int scaled_width = (scalex * gfx->width + 0x7fff) >> 16;
  2255.     int scaled_height = (scaley * gfx->height + 0x7fff) >> 16;
  2256.     int pixels_to_skip = 0, xclipped = 0;
  2257.     int dx, dy, ex, ey;
  2258.     int y, sourcey;
  2259.  
  2260.     /* make sure we didn't end up with 0 */
  2261.     if (scaled_width == 0) scaled_width = 1;
  2262.     if (scaled_height == 0) scaled_height = 1;
  2263.  
  2264.     /* compute the remaining parameters */
  2265.     dx = (gfx->width << 16) / scaled_width;
  2266.     dy = (gfx->height << 16) / scaled_height;
  2267.     ex = sx + scaled_width - 1;
  2268.     ey = sy + scaled_height - 1;
  2269.     sourcey = dy / 2;
  2270.  
  2271.     /* left edge clip */
  2272.     if (sx < clip->min_x)
  2273.         sx = clip->min_x, xclipped = 1;
  2274.     if (sx > clip->max_x)
  2275.         return;
  2276.  
  2277.     /* right edge clip */
  2278.     if (ex > clip->max_x)
  2279.         pixels_to_skip = ex - clip->max_x, xclipped = 1;
  2280.     else if (ex < clip->min_x)
  2281.         return;
  2282.  
  2283.     /* top edge clip */
  2284.     if (sy < clip->min_y)
  2285.     {
  2286.         sourcey += (clip->min_y - sy) * dy;
  2287.         sy = clip->min_y;
  2288.     }
  2289.     else if (sy > clip->max_y)
  2290.         return;
  2291.  
  2292.     /* bottom edge clip */
  2293.     if (ey > clip->max_y)
  2294.         ey = clip->max_y;
  2295.     else if (ey < clip->min_y)
  2296.         return;
  2297.  
  2298.     /* loop top to bottom */
  2299.     for (y = sy; y <= ey; y++, sourcey += dy)
  2300.     {
  2301.         UINT8 *dest = &bitmap->line[y][ex];
  2302.         int j, sourcex = dx / 2, rle_end = 0;
  2303.         const UINT16 *base;
  2304.         int entry_count;
  2305.  
  2306.         /* loop until we hit the row we're on */
  2307.         for ( ; current_row != (sourcey >> 16); current_row++)
  2308.             row_start += 1 + *row_start;
  2309.  
  2310.         /* grab our starting parameters from this row */
  2311.         base = row_start;
  2312.         entry_count = *base++;
  2313.  
  2314.         /* non-clipped case */
  2315.         if (!xclipped)
  2316.         {
  2317.             /* decode the pixels */
  2318.             for (j = 0; j < entry_count; j++)
  2319.             {
  2320.                 int word = *base++;
  2321.                 int count, value;
  2322.  
  2323.                 /* decode the low byte first */
  2324.                 count = table[word & 0xff];
  2325.                 value = count & 0xff;
  2326.                 rle_end += (count & 0xff00) << 8;
  2327.  
  2328.                 /* store copies of the value until we pass the end of this chunk */
  2329.                 if (value)
  2330.                 {
  2331.                     value = palette[value];
  2332.                     while (sourcex < rle_end)
  2333.                         *dest-- = value, sourcex += dx;
  2334.                 }
  2335.                 else
  2336.                 {
  2337.                     while (sourcex < rle_end)
  2338.                         dest--, sourcex += dx;
  2339.                 }
  2340.  
  2341.                 /* decode the upper byte second */
  2342.                 count = table[word >> 8];
  2343.                 value = count & 0xff;
  2344.                 rle_end += (count & 0xff00) << 8;
  2345.  
  2346.                 /* store copies of the value until we pass the end of this chunk */
  2347.                 if (value)
  2348.                 {
  2349.                     value = palette[value];
  2350.                     while (sourcex < rle_end)
  2351.                         *dest-- = value, sourcex += dx;
  2352.                 }
  2353.                 else
  2354.                 {
  2355.                     while (sourcex < rle_end)
  2356.                         dest--, sourcex += dx;
  2357.                 }
  2358.             }
  2359.         }
  2360.  
  2361.         /* clipped case */
  2362.         else
  2363.         {
  2364.             const UINT8 *start = &bitmap->line[y][sx];
  2365.             int to_be_skipped = pixels_to_skip;
  2366.  
  2367.             /* decode the pixels */
  2368.             for (j = 0; j < entry_count && dest >= start; j++)
  2369.             {
  2370.                 int word = *base++;
  2371.                 int count, value;
  2372.  
  2373.                 /* decode the low byte first */
  2374.                 count = table[word & 0xff];
  2375.                 value = count & 0xff;
  2376.                 rle_end += (count & 0xff00) << 8;
  2377.  
  2378.                 /* store copies of the value until we pass the end of this chunk */
  2379.                 if (to_be_skipped)
  2380.                 {
  2381.                     while (to_be_skipped && sourcex < rle_end)
  2382.                         dest--, sourcex += dx, to_be_skipped--;
  2383.                     if (to_be_skipped) goto next1;
  2384.                 }
  2385.                 if (value)
  2386.                 {
  2387.                     value = palette[value];
  2388.                     while (sourcex < rle_end && dest >= start)
  2389.                         *dest-- = value, sourcex += dx;
  2390.                 }
  2391.                 else
  2392.                 {
  2393.                     while (sourcex < rle_end)
  2394.                         dest--, sourcex += dx;
  2395.                 }
  2396.  
  2397.             next1:
  2398.                 /* decode the upper byte second */
  2399.                 count = table[word >> 8];
  2400.                 value = count & 0xff;
  2401.                 rle_end += (count & 0xff00) << 8;
  2402.  
  2403.                 /* store copies of the value until we pass the end of this chunk */
  2404.                 if (to_be_skipped)
  2405.                 {
  2406.                     while (to_be_skipped && sourcex < rle_end)
  2407.                         dest--, sourcex += dx, to_be_skipped--;
  2408.                     if (to_be_skipped) goto next2;
  2409.                 }
  2410.                 if (value)
  2411.                 {
  2412.                     value = palette[value];
  2413.                     while (sourcex < rle_end && dest >= start)
  2414.                         *dest-- = value, sourcex += dx;
  2415.                 }
  2416.                 else
  2417.                 {
  2418.                     while (sourcex < rle_end)
  2419.                         dest--, sourcex += dx;
  2420.                 }
  2421.             next2:
  2422.                 ;
  2423.             }
  2424.         }
  2425.     }
  2426. }
  2427.  
  2428.  
  2429. /*
  2430.  *    Draw a horizontally-flipped RLE-compressed object
  2431.  *
  2432.  *    What it says. RLE decoding is performed on the fly to a 16-bit bitmap.
  2433.  *
  2434.  */
  2435.  
  2436. void draw_rle_zoom_hflip_16(struct osd_bitmap *bitmap, const struct atarigen_rle_descriptor *gfx,
  2437.         UINT32 color, int flipy, int sx, int sy, int scalex, int scaley,
  2438.         const struct rectangle *clip)
  2439. {
  2440.     const UINT16 *palette = &rle_colortable[color];
  2441.     const UINT16 *row_start = gfx->data;
  2442.     const UINT16 *table = gfx->table;
  2443.     volatile int current_row = 0;
  2444.  
  2445.     int scaled_width = (scalex * gfx->width + 0x7fff) >> 16;
  2446.     int scaled_height = (scaley * gfx->height + 0x7fff) >> 16;
  2447.     int pixels_to_skip = 0, xclipped = 0;
  2448.     int dx, dy, ex, ey;
  2449.     int y, sourcey;
  2450.  
  2451.     /* make sure we didn't end up with 0 */
  2452.     if (scaled_width == 0) scaled_width = 1;
  2453.     if (scaled_height == 0) scaled_height = 1;
  2454.  
  2455.     /* compute the remaining parameters */
  2456.     dx = (gfx->width << 16) / scaled_width;
  2457.     dy = (gfx->height << 16) / scaled_height;
  2458.     ex = sx + scaled_width - 1;
  2459.     ey = sy + scaled_height - 1;
  2460.     sourcey = dy / 2;
  2461.  
  2462.     /* left edge clip */
  2463.     if (sx < clip->min_x)
  2464.         sx = clip->min_x, xclipped = 1;
  2465.     if (sx > clip->max_x)
  2466.         return;
  2467.  
  2468.     /* right edge clip */
  2469.     if (ex > clip->max_x)
  2470.         pixels_to_skip = ex - clip->max_x, xclipped = 1;
  2471.     else if (ex < clip->min_x)
  2472.         return;
  2473.  
  2474.     /* top edge clip */
  2475.     if (sy < clip->min_y)
  2476.     {
  2477.         sourcey += (clip->min_y - sy) * dy;
  2478.         sy = clip->min_y;
  2479.     }
  2480.     else if (sy > clip->max_y)
  2481.         return;
  2482.  
  2483.     /* bottom edge clip */
  2484.     if (ey > clip->max_y)
  2485.         ey = clip->max_y;
  2486.     else if (ey < clip->min_y)
  2487.         return;
  2488.  
  2489.     /* loop top to bottom */
  2490.     for (y = sy; y <= ey; y++, sourcey += dy)
  2491.     {
  2492.         UINT16 *dest = (UINT16 *)&bitmap->line[y][ex * 2];
  2493.         int j, sourcex = dx / 2, rle_end = 0;
  2494.         const UINT16 *base;
  2495.         int entry_count;
  2496.  
  2497.         /* loop until we hit the row we're on */
  2498.         for ( ; current_row != (sourcey >> 16); current_row++)
  2499.             row_start += 1 + *row_start;
  2500.  
  2501.         /* grab our starting parameters from this row */
  2502.         base = row_start;
  2503.         entry_count = *base++;
  2504.  
  2505.         /* non-clipped case */
  2506.         if (!xclipped)
  2507.         {
  2508.             /* decode the pixels */
  2509.             for (j = 0; j < entry_count; j++)
  2510.             {
  2511.                 int word = *base++;
  2512.                 int count, value;
  2513.  
  2514.                 /* decode the low byte first */
  2515.                 count = table[word & 0xff];
  2516.                 value = count & 0xff;
  2517.                 rle_end += (count & 0xff00) << 8;
  2518.  
  2519.                 /* store copies of the value until we pass the end of this chunk */
  2520.                 if (value)
  2521.                 {
  2522.                     value = palette[value];
  2523.                     while (sourcex < rle_end)
  2524.                         *dest-- = value, sourcex += dx;
  2525.                 }
  2526.                 else
  2527.                 {
  2528.                     while (sourcex < rle_end)
  2529.                         dest--, sourcex += dx;
  2530.                 }
  2531.  
  2532.                 /* decode the upper byte second */
  2533.                 count = table[word >> 8];
  2534.                 value = count & 0xff;
  2535.                 rle_end += (count & 0xff00) << 8;
  2536.  
  2537.                 /* store copies of the value until we pass the end of this chunk */
  2538.                 if (value)
  2539.                 {
  2540.                     value = palette[value];
  2541.                     while (sourcex < rle_end)
  2542.                         *dest-- = value, sourcex += dx;
  2543.                 }
  2544.                 else
  2545.                 {
  2546.                     while (sourcex < rle_end)
  2547.                         dest--, sourcex += dx;
  2548.                 }
  2549.             }
  2550.         }
  2551.  
  2552.         /* clipped case */
  2553.         else
  2554.         {
  2555.             const UINT16 *start = (const UINT16 *)&bitmap->line[y][sx * 2];
  2556.             int to_be_skipped = pixels_to_skip;
  2557.  
  2558.             /* decode the pixels */
  2559.             for (j = 0; j < entry_count && dest >= start; j++)
  2560.             {
  2561.                 int word = *base++;
  2562.                 int count, value;
  2563.  
  2564.                 /* decode the low byte first */
  2565.                 count = table[word & 0xff];
  2566.                 value = count & 0xff;
  2567.                 rle_end += (count & 0xff00) << 8;
  2568.  
  2569.                 /* store copies of the value until we pass the end of this chunk */
  2570.                 if (to_be_skipped)
  2571.                 {
  2572.                     while (to_be_skipped && sourcex < rle_end)
  2573.                         dest--, sourcex += dx, to_be_skipped--;
  2574.                     if (to_be_skipped) goto next3;
  2575.                 }
  2576.                 if (value)
  2577.                 {
  2578.                     value = palette[value];
  2579.                     while (sourcex < rle_end && dest >= start)
  2580.                         *dest-- = value, sourcex += dx;
  2581.                 }
  2582.                 else
  2583.                 {
  2584.                     while (sourcex < rle_end)
  2585.                         dest--, sourcex += dx;
  2586.                 }
  2587.  
  2588.             next3:
  2589.                 /* decode the upper byte second */
  2590.                 count = table[word >> 8];
  2591.                 value = count & 0xff;
  2592.                 rle_end += (count & 0xff00) << 8;
  2593.  
  2594.                 /* store copies of the value until we pass the end of this chunk */
  2595.                 if (to_be_skipped)
  2596.                 {
  2597.                     while (to_be_skipped && sourcex < rle_end)
  2598.                         dest--, sourcex += dx, to_be_skipped--;
  2599.                     if (to_be_skipped) goto next4;
  2600.                 }
  2601.                 if (value)
  2602.                 {
  2603.                     value = palette[value];
  2604.                     while (sourcex < rle_end && dest >= start)
  2605.                         *dest-- = value, sourcex += dx;
  2606.                 }
  2607.                 else
  2608.                 {
  2609.                     while (sourcex < rle_end)
  2610.                         dest--, sourcex += dx;
  2611.                 }
  2612.             next4:
  2613.                 ;
  2614.             }
  2615.         }
  2616.     }
  2617. }
  2618.  
  2619.  
  2620. /*--------------------------------------------------------------------------
  2621.  
  2622.     Playfield rendering
  2623.  
  2624.         atarigen_pf_state - data block describing the playfield
  2625.  
  2626.         atarigen_pf_callback - called back for each chunk during processing
  2627.  
  2628.         atarigen_pf_init - initializes and configures the playfield state
  2629.         atarigen_pf_free - frees all memory allocated by atarigen_pf_init
  2630.         atarigen_pf_reset - reset for a new frame (use only if not using interrupt system)
  2631.         atarigen_pf_update - updates the playfield state for the given scanline
  2632.         atarigen_pf_process - processes the current list of parameters
  2633.  
  2634.         atarigen_pf2_init - same as above but for a second playfield
  2635.         atarigen_pf2_free - same as above but for a second playfield
  2636.         atarigen_pf2_reset - same as above but for a second playfield
  2637.         atarigen_pf2_update - same as above but for a second playfield
  2638.         atarigen_pf2_process - same as above but for a second playfield
  2639.  
  2640. --------------------------------------------------------------------------*/
  2641.  
  2642. /* types */
  2643. struct playfield_data
  2644. {
  2645.     struct osd_bitmap *bitmap;
  2646.     UINT8 *dirty;
  2647.     UINT8 *visit;
  2648.  
  2649.     int tilewidth;
  2650.     int tileheight;
  2651.     int tilewidth_shift;
  2652.     int tileheight_shift;
  2653.     int xtiles_mask;
  2654.     int ytiles_mask;
  2655.  
  2656.     int entries;
  2657.     int *scanline;
  2658.     struct atarigen_pf_state *state;
  2659.     struct atarigen_pf_state *last_state;
  2660. };
  2661.  
  2662. /* globals */
  2663. struct osd_bitmap *atarigen_pf_bitmap;
  2664. UINT8 *atarigen_pf_dirty;
  2665. UINT8 *atarigen_pf_visit;
  2666.  
  2667. struct osd_bitmap *atarigen_pf2_bitmap;
  2668. UINT8 *atarigen_pf2_dirty;
  2669. UINT8 *atarigen_pf2_visit;
  2670.  
  2671. struct osd_bitmap *atarigen_pf_overrender_bitmap;
  2672. UINT16 atarigen_overrender_colortable[32];
  2673.  
  2674. /* statics */
  2675. static struct playfield_data playfield;
  2676. static struct playfield_data playfield2;
  2677.  
  2678. /* prototypes */
  2679. static int internal_pf_init(struct playfield_data *pf, const struct atarigen_pf_desc *source_desc);
  2680. static void internal_pf_free(struct playfield_data *pf);
  2681. static void internal_pf_reset(struct playfield_data *pf);
  2682. static void internal_pf_update(struct playfield_data *pf, const struct atarigen_pf_state *state, int scanline);
  2683. static void internal_pf_process(struct playfield_data *pf, atarigen_pf_callback callback, void *param, const struct rectangle *clip);
  2684. static int compute_shift(int size);
  2685. static int compute_mask(int count);
  2686.  
  2687.  
  2688. /*
  2689.  *    Playfield render initialization
  2690.  *
  2691.  *    Allocates memory for the playfield and initializes all structures.
  2692.  *
  2693.  */
  2694.  
  2695. static int internal_pf_init(struct playfield_data *pf, const struct atarigen_pf_desc *source_desc)
  2696. {
  2697.     /* allocate the bitmap */
  2698.     if (!source_desc->noscroll)
  2699.         pf->bitmap = osd_new_bitmap(source_desc->tilewidth * source_desc->xtiles,
  2700.                                     source_desc->tileheight * source_desc->ytiles,
  2701.                                     Machine->scrbitmap->depth);
  2702.     else
  2703.         pf->bitmap = osd_new_bitmap(Machine->drv->screen_width,
  2704.                                     Machine->drv->screen_height,
  2705.                                     Machine->scrbitmap->depth);
  2706.     if (!pf->bitmap)
  2707.         return 1;
  2708.  
  2709.     /* allocate the dirty tile map */
  2710.     pf->dirty = malloc(source_desc->xtiles * source_desc->ytiles);
  2711.     if (!pf->dirty)
  2712.     {
  2713.         internal_pf_free(pf);
  2714.         return 1;
  2715.     }
  2716.     memset(pf->dirty, 0xff, source_desc->xtiles * source_desc->ytiles);
  2717.  
  2718.     /* allocate the visitation map */
  2719.     pf->visit = malloc(source_desc->xtiles * source_desc->ytiles);
  2720.     if (!pf->visit)
  2721.     {
  2722.         internal_pf_free(pf);
  2723.         return 1;
  2724.     }
  2725.  
  2726.     /* allocate the list of scanlines */
  2727.     pf->scanline = malloc(source_desc->ytiles * source_desc->tileheight * sizeof(int));
  2728.     if (!pf->scanline)
  2729.     {
  2730.         internal_pf_free(pf);
  2731.         return 1;
  2732.     }
  2733.  
  2734.     /* allocate the list of parameters */
  2735.     pf->state = malloc(source_desc->ytiles * source_desc->tileheight * sizeof(struct atarigen_pf_state));
  2736.     if (!pf->state)
  2737.     {
  2738.         internal_pf_free(pf);
  2739.         return 1;
  2740.     }
  2741.  
  2742.     /* copy the basic data */
  2743.     pf->tilewidth = source_desc->tilewidth;
  2744.     pf->tileheight = source_desc->tileheight;
  2745.     pf->tilewidth_shift = compute_shift(source_desc->tilewidth);
  2746.     pf->tileheight_shift = compute_shift(source_desc->tileheight);
  2747.     pf->xtiles_mask = compute_mask(source_desc->xtiles);
  2748.     pf->ytiles_mask = compute_mask(source_desc->ytiles);
  2749.  
  2750.     /* initialize the last state to all zero */
  2751.     pf->last_state = pf->state;
  2752.     memset(pf->last_state, 0, sizeof(*pf->last_state));
  2753.  
  2754.     /* reset */
  2755.     internal_pf_reset(pf);
  2756.  
  2757.     return 0;
  2758. }
  2759.  
  2760. int atarigen_pf_init(const struct atarigen_pf_desc *source_desc)
  2761. {
  2762.     int result = internal_pf_init(&playfield, source_desc);
  2763.     if (!result)
  2764.     {
  2765.         /* allocate the overrender bitmap */
  2766.         atarigen_pf_overrender_bitmap = osd_new_bitmap(Machine->drv->screen_width, Machine->drv->screen_height, Machine->scrbitmap->depth);
  2767.         if (!atarigen_pf_overrender_bitmap)
  2768.         {
  2769.             internal_pf_free(&playfield);
  2770.             return 1;
  2771.         }
  2772.  
  2773.         atarigen_pf_bitmap = playfield.bitmap;
  2774.         atarigen_pf_dirty = playfield.dirty;
  2775.         atarigen_pf_visit = playfield.visit;
  2776.     }
  2777.     return result;
  2778. }
  2779.  
  2780. int atarigen_pf2_init(const struct atarigen_pf_desc *source_desc)
  2781. {
  2782.     int result = internal_pf_init(&playfield2, source_desc);
  2783.     if (!result)
  2784.     {
  2785.         atarigen_pf2_bitmap = playfield2.bitmap;
  2786.         atarigen_pf2_dirty = playfield2.dirty;
  2787.         atarigen_pf2_visit = playfield2.visit;
  2788.     }
  2789.     return result;
  2790. }
  2791.  
  2792.  
  2793. /*
  2794.  *    Playfield render free
  2795.  *
  2796.  *    Frees all memory allocated by the playfield system.
  2797.  *
  2798.  */
  2799.  
  2800. static void internal_pf_free(struct playfield_data *pf)
  2801. {
  2802.     if (pf->bitmap)
  2803.         osd_free_bitmap(pf->bitmap);
  2804.     pf->bitmap = NULL;
  2805.  
  2806.     if (pf->dirty)
  2807.         free(pf->dirty);
  2808.     pf->dirty = NULL;
  2809.  
  2810.     if (pf->visit)
  2811.         free(pf->visit);
  2812.     pf->visit = NULL;
  2813.  
  2814.     if (pf->scanline)
  2815.         free(pf->scanline);
  2816.     pf->scanline = NULL;
  2817.  
  2818.     if (pf->state)
  2819.         free(pf->state);
  2820.     pf->state = NULL;
  2821. }
  2822.  
  2823. void atarigen_pf_free(void)
  2824. {
  2825.     internal_pf_free(&playfield);
  2826.  
  2827.     /* free the overrender bitmap */
  2828.     if (atarigen_pf_overrender_bitmap)
  2829.         osd_free_bitmap(atarigen_pf_overrender_bitmap);
  2830.     atarigen_pf_overrender_bitmap = NULL;
  2831. }
  2832.  
  2833. void atarigen_pf2_free(void)
  2834. {
  2835.     internal_pf_free(&playfield2);
  2836. }
  2837.  
  2838.  
  2839. /*
  2840.  *    Playfield render reset
  2841.  *
  2842.  *    Resets the playfield system for a new frame. Note that this is automatically called
  2843.  *    if you're using the interrupt system.
  2844.  *
  2845.  */
  2846.  
  2847. void internal_pf_reset(struct playfield_data *pf)
  2848. {
  2849.     /* verify memory has been allocated -- we're called even if we're not used */
  2850.     if (pf->scanline && pf->state)
  2851.     {
  2852.         pf->entries = 0;
  2853.         internal_pf_update(pf, pf->last_state, 0);
  2854.     }
  2855. }
  2856.  
  2857. void atarigen_pf_reset(void)
  2858. {
  2859.     internal_pf_reset(&playfield);
  2860. }
  2861.  
  2862. void atarigen_pf2_reset(void)
  2863. {
  2864.     internal_pf_reset(&playfield2);
  2865. }
  2866.  
  2867.  
  2868. /*
  2869.  *    Playfield render update
  2870.  *
  2871.  *    Sets the parameters for a given scanline.
  2872.  *
  2873.  */
  2874.  
  2875. void internal_pf_update(struct playfield_data *pf, const struct atarigen_pf_state *state, int scanline)
  2876. {
  2877.     if (pf->entries > 0)
  2878.     {
  2879.         /* if the current scanline matches the previous one, just overwrite */
  2880.         if (pf->scanline[pf->entries - 1] == scanline)
  2881.             pf->entries--;
  2882.  
  2883.         /* if the current data matches the previous data, ignore it */
  2884.         else if (pf->last_state->hscroll == state->hscroll &&
  2885.                  pf->last_state->vscroll == state->vscroll &&
  2886.                  pf->last_state->param[0] == state->param[0] &&
  2887.                  pf->last_state->param[1] == state->param[1])
  2888.             return;
  2889.     }
  2890.  
  2891.     /* remember this entry as the last set of parameters */
  2892.     pf->last_state = &pf->state[pf->entries];
  2893.  
  2894.     /* copy in the data */
  2895.     pf->scanline[pf->entries] = scanline;
  2896.     pf->state[pf->entries++] = *state;
  2897.  
  2898.     /* set the final scanline to be huge -- it will be clipped during processing */
  2899.     pf->scanline[pf->entries] = 100000;
  2900. }
  2901.  
  2902. void atarigen_pf_update(const struct atarigen_pf_state *state, int scanline)
  2903. {
  2904.     internal_pf_update(&playfield, state, scanline);
  2905. }
  2906.  
  2907. void atarigen_pf2_update(const struct atarigen_pf_state *state, int scanline)
  2908. {
  2909.     internal_pf_update(&playfield2, state, scanline);
  2910. }
  2911.  
  2912.  
  2913. /*
  2914.  *    Playfield render process
  2915.  *
  2916.  *    Processes the playfield in chunks.
  2917.  *
  2918.  */
  2919.  
  2920. void internal_pf_process(struct playfield_data *pf, atarigen_pf_callback callback, void *param, const struct rectangle *clip)
  2921. {
  2922.     struct rectangle curclip;
  2923.     struct rectangle tiles;
  2924.     int y;
  2925.  
  2926.     /* preinitialization */
  2927.     curclip.min_x = clip->min_x;
  2928.     curclip.max_x = clip->max_x;
  2929.  
  2930.     /* loop over all entries */
  2931.     for (y = 0; y < pf->entries; y++)
  2932.     {
  2933.         struct atarigen_pf_state *current = &pf->state[y];
  2934.  
  2935.         /* determine the clip rect */
  2936.         curclip.min_y = pf->scanline[y];
  2937.         curclip.max_y = pf->scanline[y + 1] - 1;
  2938.  
  2939.         /* skip if we're clipped out */
  2940.         if (curclip.min_y > clip->max_y || curclip.max_y < clip->min_y)
  2941.             continue;
  2942.  
  2943.         /* clip the clipper */
  2944.         if (curclip.min_y < clip->min_y)
  2945.             curclip.min_y = clip->min_y;
  2946.         if (curclip.max_y > clip->max_y)
  2947.             curclip.max_y = clip->max_y;
  2948.  
  2949.         /* determine the tile rect */
  2950.         tiles.min_x = ((current->hscroll + curclip.min_x) >> pf->tilewidth_shift) & pf->xtiles_mask;
  2951.         tiles.max_x = ((current->hscroll + curclip.max_x + pf->tilewidth) >> pf->tilewidth_shift) & pf->xtiles_mask;
  2952.         tiles.min_y = ((current->vscroll + curclip.min_y) >> pf->tileheight_shift) & pf->ytiles_mask;
  2953.         tiles.max_y = ((current->vscroll + curclip.max_y + pf->tileheight) >> pf->tileheight_shift) & pf->ytiles_mask;
  2954.  
  2955.         /* call the callback */
  2956.         (*callback)(&curclip, &tiles, current, param);
  2957.     }
  2958. }
  2959.  
  2960. void atarigen_pf_process(atarigen_pf_callback callback, void *param, const struct rectangle *clip)
  2961. {
  2962.     internal_pf_process(&playfield, callback, param, clip);
  2963. }
  2964.  
  2965. void atarigen_pf2_process(atarigen_pf_callback callback, void *param, const struct rectangle *clip)
  2966. {
  2967.     internal_pf_process(&playfield2, callback, param, clip);
  2968. }
  2969.  
  2970.  
  2971. /*
  2972.  *    Shift value computer
  2973.  *
  2974.  *    Determines the log2(value).
  2975.  *
  2976.  */
  2977.  
  2978. static int compute_shift(int size)
  2979. {
  2980.     int i;
  2981.  
  2982.     /* loop until we shift to zero */
  2983.     for (i = 0; i < 32; i++)
  2984.         if (!(size >>= 1))
  2985.             break;
  2986.     return i;
  2987. }
  2988.  
  2989.  
  2990. /*
  2991.  *    Mask computer
  2992.  *
  2993.  *    Determines the best mask to use for the given value.
  2994.  *
  2995.  */
  2996.  
  2997. static int compute_mask(int count)
  2998. {
  2999.     int shift = compute_shift(count);
  3000.  
  3001.     /* simple case - count is an even power of 2 */
  3002.     if (count == (1 << shift))
  3003.         return count - 1;
  3004.  
  3005.     /* slightly less simple case - round up to the next power of 2 */
  3006.     else
  3007.         return (1 << (shift + 1)) - 1;
  3008. }
  3009.  
  3010.  
  3011.  
  3012.  
  3013.  
  3014. /*--------------------------------------------------------------------------
  3015.  
  3016.     Misc Video stuff
  3017.  
  3018.         atarigen_get_hblank - returns the current HBLANK state
  3019.         atarigen_halt_until_hblank_0_w - write handler for a HBLANK halt
  3020.         atarigen_666_paletteram_w - 6-6-6 special RGB paletteram handler
  3021.         atarigen_expanded_666_paletteram_w - byte version of above
  3022.  
  3023. --------------------------------------------------------------------------*/
  3024.  
  3025. /* prototypes */
  3026. static void unhalt_cpu(int param);
  3027.  
  3028.  
  3029. /*
  3030.  *    Compute HBLANK state
  3031.  *
  3032.  *    Returns a guesstimate about the current HBLANK state, based on the assumption that
  3033.  *    HBLANK represents 10% of the scanline period.
  3034.  *
  3035.  */
  3036.  
  3037. int atarigen_get_hblank(void)
  3038. {
  3039.     return (cpu_gethorzbeampos() > (Machine->drv->screen_width * 9 / 10));
  3040. }
  3041.  
  3042.  
  3043. /*
  3044.  *    Halt CPU 0 until HBLANK
  3045.  *
  3046.  *    What it says.
  3047.  *
  3048.  */
  3049.  
  3050. WRITE_HANDLER( atarigen_halt_until_hblank_0_w )
  3051. {
  3052.     /* halt the CPU until the next HBLANK */
  3053.     int hpos = cpu_gethorzbeampos();
  3054.     int hblank = Machine->drv->screen_width * 9 / 10;
  3055.     double fraction;
  3056.  
  3057.     /* if we're in hblank, set up for the next one */
  3058.     if (hpos >= hblank)
  3059.         hblank += Machine->drv->screen_width;
  3060.  
  3061.     /* halt and set a timer to wake up */
  3062.     fraction = (double)(hblank - hpos) / (double)Machine->drv->screen_width;
  3063.     timer_set(cpu_getscanlineperiod() * fraction, 0, unhalt_cpu);
  3064.     cpu_set_halt_line(0, ASSERT_LINE);
  3065. }
  3066.  
  3067.  
  3068. /*
  3069.  *    6-6-6 RGB palette RAM handler
  3070.  *
  3071.  *    What it says.
  3072.  *
  3073.  */
  3074.  
  3075. WRITE_HANDLER( atarigen_666_paletteram_w )
  3076. {
  3077.     int oldword = READ_WORD(&paletteram[offset]);
  3078.     int newword = COMBINE_WORD(oldword,data);
  3079.     WRITE_WORD(&paletteram[offset],newword);
  3080.  
  3081.     {
  3082.         int r, g, b;
  3083.  
  3084.         r = ((newword >> 9) & 0x3e) | ((newword >> 15) & 1);
  3085.         g = ((newword >> 4) & 0x3e) | ((newword >> 15) & 1);
  3086.         b = ((newword << 1) & 0x3e) | ((newword >> 15) & 1);
  3087.  
  3088.         r = (r << 2) | (r >> 4);
  3089.         g = (g << 2) | (g >> 4);
  3090.         b = (b << 2) | (b >> 4);
  3091.  
  3092.         palette_change_color(offset / 2, r, g, b);
  3093.     }
  3094. }
  3095.  
  3096.  
  3097. /*
  3098.  *    6-6-6 RGB expanded palette RAM handler
  3099.  *
  3100.  *    What it says.
  3101.  *
  3102.  */
  3103.  
  3104. WRITE_HANDLER( atarigen_expanded_666_paletteram_w )
  3105. {
  3106.     COMBINE_WORD_MEM(&paletteram[offset], data);
  3107.  
  3108.     if (!(data & 0xff000000))
  3109.     {
  3110.         int palentry = offset / 4;
  3111.         int newword = (READ_WORD(&paletteram[palentry * 4]) & 0xff00) | (READ_WORD(&paletteram[palentry * 4 + 2]) >> 8);
  3112.  
  3113.         int r, g, b;
  3114.  
  3115.         r = ((newword >> 9) & 0x3e) | ((newword >> 15) & 1);
  3116.         g = ((newword >> 4) & 0x3e) | ((newword >> 15) & 1);
  3117.         b = ((newword << 1) & 0x3e) | ((newword >> 15) & 1);
  3118.  
  3119.         r = (r << 2) | (r >> 4);
  3120.         g = (g << 2) | (g >> 4);
  3121.         b = (b << 2) | (b >> 4);
  3122.  
  3123.         palette_change_color(palentry & 0x1ff, r, g, b);
  3124.     }
  3125. }
  3126.  
  3127.  
  3128. /*
  3129.  *    CPU unhalter
  3130.  *
  3131.  *    Timer callback to release the CPU from a halted state.
  3132.  *
  3133.  */
  3134.  
  3135. static void unhalt_cpu(int param)
  3136. {
  3137.     cpu_set_halt_line(param, CLEAR_LINE);
  3138. }
  3139.  
  3140.  
  3141.  
  3142. /*--------------------------------------------------------------------------
  3143.  
  3144.     General stuff
  3145.  
  3146.         atarigen_show_slapstic_message - display warning about slapstic
  3147.         atarigen_show_sound_message - display warning about coins
  3148.         atarigen_update_messages - update messages
  3149.  
  3150. --------------------------------------------------------------------------*/
  3151.  
  3152. /* statics */
  3153. static char *message_text[10];
  3154. static int message_countdown;
  3155.  
  3156. /*
  3157.  *    Display a warning message about slapstic protection
  3158.  *
  3159.  *    What it says.
  3160.  *
  3161.  */
  3162.  
  3163. void atarigen_show_slapstic_message(void)
  3164. {
  3165.     message_text[0] = "There are known problems with";
  3166.     message_text[1] = "later levels of this game due";
  3167.     message_text[2] = "to incomplete slapstic emulation.";
  3168.     message_text[3] = "You have been warned.";
  3169.     message_text[4] = NULL;
  3170.     message_countdown = 15 * Machine->drv->frames_per_second;
  3171. }
  3172.  
  3173.  
  3174. /*
  3175.  *    Display a warning message about sound being disabled
  3176.  *
  3177.  *    What it says.
  3178.  *
  3179.  */
  3180.  
  3181. void atarigen_show_sound_message(void)
  3182. {
  3183.     if (Machine->sample_rate == 0)
  3184.     {
  3185.         message_text[0] = "This game may have trouble accepting";
  3186.         message_text[1] = "coins, or may even behave strangely,";
  3187.         message_text[2] = "because you have disabled sound.";
  3188.         message_text[3] = NULL;
  3189.         message_countdown = 15 * Machine->drv->frames_per_second;
  3190.     }
  3191. }
  3192.  
  3193.  
  3194. /*
  3195.  *    Update on-screen messages
  3196.  *
  3197.  *    What it says.
  3198.  *
  3199.  */
  3200.  
  3201. void atarigen_update_messages(void)
  3202. {
  3203.     if (message_countdown && message_text[0])
  3204.     {
  3205.         int maxwidth = 0;
  3206.         int lines, x, y, i, j;
  3207.  
  3208.         /* first count lines and determine the maximum width */
  3209.         for (lines = 0; lines < 10; lines++)
  3210.         {
  3211.             if (!message_text[lines]) break;
  3212.             x = strlen(message_text[lines]);
  3213.             if (x > maxwidth) maxwidth = x;
  3214.         }
  3215.         maxwidth += 2;
  3216.  
  3217.         /* determine y offset */
  3218.         x = (Machine->uiwidth - Machine->uifontwidth * maxwidth) / 2;
  3219.         y = (Machine->uiheight - Machine->uifontheight * (lines + 2)) / 2;
  3220.  
  3221.         /* draw a row of spaces at the top and bottom */
  3222.         for (i = 0; i < maxwidth; i++)
  3223.         {
  3224.             ui_text(Machine->scrbitmap, " ", x + i * Machine->uifontwidth, y);
  3225.             ui_text(Machine->scrbitmap, " ", x + i * Machine->uifontwidth, y + (lines + 1) * Machine->uifontheight);
  3226.         }
  3227.         y += Machine->uifontheight;
  3228.  
  3229.         /* draw the message */
  3230.         for (i = 0; i < lines; i++)
  3231.         {
  3232.             int width = strlen(message_text[i]) * Machine->uifontwidth;
  3233.             int dx = (Machine->uifontwidth * maxwidth - width) / 2;
  3234.  
  3235.             for (j = 0; j < dx; j += Machine->uifontwidth)
  3236.             {
  3237.                 ui_text(Machine->scrbitmap, " ", x + j, y);
  3238.                 ui_text(Machine->scrbitmap, " ", x + (maxwidth - 1) * Machine->uifontwidth - j, y);
  3239.             }
  3240.  
  3241.             ui_text(Machine->scrbitmap, message_text[i], x + dx, y);
  3242.             y += Machine->uifontheight;
  3243.         }
  3244.  
  3245.         /* decrement the counter */
  3246.         message_countdown--;
  3247.  
  3248.         /* if a coin is inserted, make the message go away */
  3249.         if (keyboard_pressed(KEYCODE_5) || keyboard_pressed(KEYCODE_6) ||
  3250.             keyboard_pressed(KEYCODE_7) || keyboard_pressed(KEYCODE_8))
  3251.             message_countdown = 0;
  3252.     }
  3253.     else
  3254.         message_text[0] = NULL;
  3255. }
  3256.  
  3257.  
  3258.